ragel-6.10/0000775000175000017500000000000013065122770007540 500000000000000ragel-6.10/configure.ac0000664000175000017500000000727413065111230011745 00000000000000dnl dnl Copyright 2001-2009 Adrian Thurston dnl dnl This file is part of Ragel. dnl dnl Ragel is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl Ragel is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with Ragel; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA AC_INIT(ragel, 6.10) PUBDATE="March 2017" AM_INIT_AUTOMAKE([foreign]) AC_SUBST(PUBDATE) AC_CONFIG_HEADER(ragel/config.h) dnl Choose defaults for the build_parsers and build_manual vars. If the dist dnl file is present in the root then default to no, otherwise go for it. AS_IF([test -r $srcdir/DIST], [. $srcdir/DIST], [build_parsers=yes; build_manual=yes]) dnl dnl Enable arg to explicitly control the building of the manual dnl AC_ARG_ENABLE(manual, [ --enable-manual do we want to build the manual?], [ if test "x$enableval" = "xyes"; then build_manual=yes; else build_manual=no; fi ], ) dnl Set to true if the build system should generate parsers from ragel and kelbt dnl sources. Set to false if generated files are included and not to be built dnl (production). AM_CONDITIONAL(BUILD_PARSERS, [test "x$build_parsers" = "xyes"]) dnl Set to true if the manual should be built. AM_CONDITIONAL(BUILD_MANUAL, [test "x$build_manual" = "xyes"]) dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_CHECK_TOOL(AR, ar) AC_PROG_RANLIB dnl Set test on c++ compiler. AC_LANG_CPLUSPLUS dnl Check for definition of MAKE. AC_PROG_MAKE_SET # Checks to carry out if we are building parsers. if test "x$build_parsers" = "xyes"; then AC_CHECK_PROG(RAGEL, ragel, ragel) if test -z "$RAGEL"; then echo echo "error: ragel is required to build the parsers" echo exit 1 fi AC_CHECK_PROG(KELBT, kelbt, kelbt) if test -z "$KELBT"; then echo echo "error: kelbt is required to build the parsers" echo exit 1 fi fi # Checks to carry out if we are building the manual. if test "x$build_manual" = "xyes"; then AC_CHECK_PROG(FIG2DEV, fig2dev, fig2dev) if test -z "$FIG2DEV"; then echo echo "error: fig2dev is required to build the manual (maybe use --disable-manual)" echo exit 1 fi AC_CHECK_PROG(PDFLATEX, pdflatex, pdflatex) if test -z "$PDFLATEX"; then echo echo "error: pdflatex is required to build the manual (maybe use --disable-manual)" echo exit 1 fi fi dnl Check for the D compiler AC_CHECK_PROG(GDC, gdc, gdc) dnl Check for the Objective-C compiler AC_MSG_CHECKING([for the Objective-C compiler]) cat > conftest.m </dev/null; then GOBJC="gcc -x objective-c" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AC_SUBST(GOBJC) dnl Check for the Java compiler. AC_CHECK_PROG(JAVAC, javac, javac) dnl Check for TXL. AC_CHECK_PROG(TXL, txl, txl) dnl Check for Ruby. AC_CHECK_PROG(RUBY, ruby, ruby) dnl Check for the C# compiler. AC_CHECK_PROG(GMCS, gmcs, gmcs) dnl Check for the Go compiler. AC_CHECK_PROG(GOBIN, go, go build) dnl write output files AC_OUTPUT( [ Makefile ragel/Makefile aapl/Makefile doc/Makefile doc/ragel.1 contrib/Makefile test/Makefile test/runtests examples/Makefile ], [chmod +x test/runtests] ) echo "configuration of ragel complete" ragel-6.10/AUTHORS0000664000175000017500000000001513065111230010511 00000000000000See CREDITS. ragel-6.10/test/0000775000175000017500000000000013065122770010517 500000000000000ragel-6.10/test/erract4.rl0000664000175000017500000000416413065111230012334 00000000000000/* * @LANG: obj-c */ #include #include #define IDENT_BUFLEN 256 @interface ErrAct : Object { @public 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. - (int) initFsm; // 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) executeWithData:(const char *)data len:(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; @end @implementation ErrAct %%{ machine ErrAct; # The data that is to go into the fsm structure. action hello_fails { printf("hello fails\n");} newline = ( any | '\n' @{printf("newline\n");} )*; hello = 'hello\n'* $^hello_fails @/hello_fails; main := newline | hello; }%% %% write data; - (int) initFsm; { %% write init; return 1; } - (void) executeWithData:(const char *)_data len:(int)_len; { const char *p = _data; const char *pe = _data + _len; const char *eof = pe; %% write exec; } - (int) finish; { if ( cs == ErrAct_error ) return -1; else if ( cs >= ErrAct_first_final ) return 1; return 0; } @end #include #include #define BUFSIZE 2048 ErrAct *fsm; char buf[BUFSIZE]; void test( char *buf ) { int len = strlen(buf); fsm = [[ErrAct alloc] init]; [fsm initFsm]; [fsm executeWithData:buf len:len]; if ( [fsm finish] > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "hello\n" "hello\n" "hello\n" ); test( "hello\n" "hello\n" "hello there\n" ); test( "hello\n" "hello\n" "he" ); test( "" ); return 0; } #ifdef _____OUTPUT_____ newline newline newline ACCEPT newline newline hello fails newline ACCEPT newline newline hello fails ACCEPT ACCEPT #endif ragel-6.10/test/element2.rl0000664000175000017500000000176013065111230012502 00000000000000/* * @LANG: c */ #include struct LangEl { int key; char *name; }; struct fsm { int cs; }; %%{ machine fsm; alphtype int; getkey fpc->key; variable cs fsm->cs; action a1 {} action a2 {} action a3 {} main := ( 1 2* 3 ) ${printf("%s\n", fpc->name);} %/{printf("accept\n");}; }%% %% write data; void fsm_init( struct fsm *fsm ) { %% write init; } void fsm_execute( struct fsm *fsm, struct LangEl *_data, int _len ) { struct LangEl *p = _data; struct LangEl *pe = _data+_len; struct LangEl *eof = pe; %% write exec; } int fsm_finish( struct fsm *fsm ) { if ( fsm->cs == fsm_error ) return -1; if ( fsm->cs >= fsm_first_final ) return 1; return 0; } int main() { static struct fsm fsm; static struct LangEl lel[] = { {1, "one"}, {2, "two-a"}, {2, "two-b"}, {2, "two-c"}, {3, "three"} }; fsm_init( &fsm ); fsm_execute( &fsm, lel, 5 ); fsm_finish( &fsm ); return 0; } #ifdef _____OUTPUT_____ one two-a two-b two-c three accept #endif ragel-6.10/test/cppscan3.rl0000664000175000017500000001113613065111230012477 00000000000000/* * @LANG: c++ */ #include #include using namespace std; #define TK_Dlit 192 #define TK_Slit 193 #define TK_Float 194 #define TK_Id 195 #define TK_NameSep 197 #define TK_Arrow 211 #define TK_PlusPlus 212 #define TK_MinusMinus 213 #define TK_ArrowStar 214 #define TK_DotStar 215 #define TK_ShiftLeft 216 #define TK_ShiftRight 217 #define TK_IntegerDecimal 218 #define TK_IntegerOctal 219 #define TK_IntegerHex 220 #define TK_EqualsEquals 223 #define TK_NotEquals 224 #define TK_AndAnd 225 #define TK_OrOr 226 #define TK_MultAssign 227 #define TK_DivAssign 228 #define TK_PercentAssign 229 #define TK_PlusAssign 230 #define TK_MinusAssign 231 #define TK_AmpAssign 232 #define TK_CaretAssign 233 #define TK_BarAssign 234 #define TK_DotDotDot 240 #define TK_Whitespace 241 #define TK_Comment 242 #define BUFSIZE 4096 char buf[BUFSIZE]; struct Scanner { int cs, act; const char *ts, *te; void token( int tok ); void run(); void init( ); void execute( const char *data, int len ); int finish( ); }; %%{ machine Scanner; main := |* # Single and double literals. ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) => { token( TK_Slit );}; ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) => { token( TK_Dlit );}; # Identifiers ( [a-zA-Z_] [a-zA-Z0-9_]* ) =>{ token( TK_Id );}; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) => { token( TK_Float );}; # Integer decimal. Leading part buffered by float. ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) => { token( TK_IntegerDecimal );}; # Integer octal. Leading part buffered by float. ( '0' [0-9]+ [ulUL]{0,2} ) => { token( TK_IntegerOctal );}; # Integer hex. Leading 0 buffered by float. ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) => { token( TK_IntegerHex );}; # Only buffer the second item, first buffered by symbol. */ '::' => {token( TK_NameSep );}; '==' => {token( TK_EqualsEquals );}; '!=' => {token( TK_NotEquals );}; '&&' => {token( TK_AndAnd );}; '||' => {token( TK_OrOr );}; '*=' => {token( TK_MultAssign );}; '/=' => {token( TK_DivAssign );}; '%=' => {token( TK_PercentAssign );}; '+=' => {token( TK_PlusAssign );}; '-=' => {token( TK_MinusAssign );}; '&=' => {token( TK_AmpAssign );}; '^=' => {token( TK_CaretAssign );}; '|=' => {token( TK_BarAssign );}; '++' => {token( TK_PlusPlus );}; '--' => {token( TK_MinusMinus );}; '->' => {token( TK_Arrow );}; '->*' => {token( TK_ArrowStar );}; '.*' => {token( TK_DotStar );}; # Three char compounds, first item already buffered. */ '...' => { token( TK_DotDotDot );}; # Single char symbols. ( punct - [_"'] ) => { token( ts[0] );}; action comment { token( TK_Comment ); } # Comments and whitespace. '/*' ( any* $0 '*/' @1 ) => comment; '//' ( any* $0 '\n' @1 ) => comment; ( any - 33..126 )+ => { token( TK_Whitespace );}; *|; }%% %% write data; void Scanner::init( ) { %% write init; } /* Returns the count of bytes still in the buffer * (shifted to the biginning) */ void Scanner::execute( const char *data, int len ) { const char *p = data; const char *pe = data + len; const char *eof = pe; %% write exec; cout << "P: " << (p - data) << endl; } int Scanner::finish( ) { if ( cs == Scanner_error ) return -1; if ( cs >= Scanner_first_final ) return 1; return 0; } void Scanner::token( int tok ) { const char *data = ts; int len = te - ts; cout << "<" << tok << "> "; for ( int i = 0; i < len; i++ ) cout << data[i]; cout << '\n'; } void test( const char *buf ) { int len = strlen( buf ); std::ios::sync_with_stdio(false); Scanner scanner; scanner.init(); scanner.execute( buf, len ); if ( scanner.cs == Scanner_error ) { /* Machine failed before finding a token. */ cout << "PARSE ERROR" << endl; } /* FIXME: Last token may get lost. */ scanner.finish(); } int main() { test( "\"\\\"hi\" /*\n" "*/\n" "44 .44\n" "44. 44\n" "44 . 44\n" "44.44\n" "_hithere22" ); test( "'\\''\"\\n\\d'\\\"\"\n" "hi\n" "99\n" ".99\n" "99e-4\n" "->*\n" "||\n" "0x98\n" "0x\n" "//\n" "/* * */" ); test( "'\n" "'\n" ); } #ifdef _____OUTPUT_____ <192> "\"hi" <241> <242> /* */ <241> <218> 44 <241> <194> .44 <241> <194> 44. <241> <218> 44 <241> <218> 44 <241> <46> . <241> <218> 44 <241> <194> 44.44 <241> <195> _hithere22 P: 51 <193> '\'' <192> "\n\d'\"" <241> <195> hi <241> <218> 99 <241> <194> .99 <241> <194> 99e-4 <241> <214> ->* <241> <226> || <241> <220> 0x98 <241> <218> 0 <195> x <241> <242> // <242> /* * */ P: 55 P: 1 PARSE ERROR #endif ragel-6.10/test/stateact1.rl0000664000175000017500000000111213065111230012647 00000000000000/* * @LANG: indep * * Test in and out state actions. */ %% %%{ machine state_act; action a1 { prints "a1\n"; } action a2 { prints "a2\n"; } action b1 { prints "b1\n"; } action b2 { prints "b2\n"; } action c1 { prints "c1\n"; } action c2 { prints "c2\n"; } action next_again {fnext again;} hi = 'hi'; line = again: hi >to b1 >from b2 '\n' >to c1 >from c2 @next_again; main := line* >to a1 >from a2; }%% /* _____INPUT_____ "hi\nhi\n" _____INPUT_____ */ /* _____OUTPUT_____ a2 b2 c1 c2 b1 b2 c1 c2 b1 FAIL _____OUTPUT_____ */ ragel-6.10/test/include1.rl0000664000175000017500000000055313065111230012472 00000000000000/* * @LANG: c * @IGNORE: yes * * Provides definitions for include tests. */ %%{ machine include_test_1; action A {printf(" a1");} action B {printf(" b1");} action NonRef1 {printf(" nr1");} a1 = 'a' @A; b1 = 'b' @B; }%% %%{ machine include_test_2; action NonRef2 {printf(" nr2");} a2 = 'a' @{printf(" a2");}; b2 = 'b' @{printf(" b2");}; }%% ragel-6.10/test/clang3.rl0000664000175000017500000001564213065111230012142 00000000000000/* * @LANG: d * A mini C-like language scanner. */ module clang; import std.c.stdio; char[] string(char c) { char[] result = new char[2]; result[0] = c; result[1] = 0; return result[0 .. 1]; } class CLang { /* Parsing data. */ char[] identBuf; int curLine; this() { } /* State machine operation data. */ int cs; %%{ machine clang; # Function to buffer a character. action bufChar { identBuf ~= fc; } # Function to clear the buffer. action clearBuf { identBuf = null; } # Functions to dump tokens as they are matched. action ident { printf("ident(%i): %.*s\n", curLine, identBuf); } action literal { printf("literal(%i): %.*s\n", curLine, identBuf); } action float { printf("float(%i): %.*s\n", curLine, identBuf); } action int { printf("int(%i): %.*s\n", curLine, identBuf); } action hex { printf("hex(%i): 0x%.*s\n", curLine, identBuf); } action symbol { printf("symbol(%i): %.*s\n", curLine, identBuf); } # Alpha numberic characters or underscore. alnumu = alnum | '_'; # Alpha charactres or underscore. alphau = alpha | '_'; # Symbols. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving dump the symbol. symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; # Identifier. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving, dump the identifier. ident = (alphau . alnumu*) >clearBuf $bufChar %ident; # Match single characters inside literal strings. Or match # an escape sequence. Buffers the charater matched. sliteralChar = ( extend - ['\\] ) @bufChar | ( '\\' . extend @bufChar ); dliteralChar = ( extend - ["\\] ) @bufChar | ( '\\' . extend @bufChar ); # Single quote and double quota literals. At the start clear # the buffer. Upon leaving dump the literal. sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; literal = sliteral | dliteral; # Whitespace is standard ws, newlines and control codes. whitespace = any - 0x21..0x7e; # Describe both c style comments and c++ style comments. The # priority bump on tne terminator of the comments brings us # out of the extend* which matches everything. ccComment = '//' . extend* $0 . '\n' @1; cComment = '/*' . extend* $0 . '*/' @1; # Match an integer. We don't bother clearing the buf or filling it. # The float machine overlaps with int and it will do it. int = digit+ %int; # Match a float. Upon entering the machine clear the buf, buffer # characters on every trans and dump the float upon leaving. float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; # Match a hex. Upon entering the hex part, clear the buf, buffer characters # on every trans and dump the hex on leaving transitions. hex = '0x' . xdigit+ >clearBuf $bufChar %hex; # Or together all the lanuage elements. fin = ( ccComment | cComment | symbol | ident | literal | whitespace | int | float | hex ); # Star the language elements. It is critical in this type of application # that we decrease the priority of out transitions before doing so. This # is so that when we see 'aa' we stay in the fin machine to match an ident # of length two and not wrap around to the front to match two idents of # length one. clang_main = ( fin $1 %0 )*; # This machine matches everything, taking note of newlines. newline = ( any | '\n' @{ curLine++; } )*; # The final fsm is the lexer intersected with the newline machine which # will count lines for us. Since the newline machine accepts everything, # the strings accepted is goverened by the clang_main machine, onto which # the newline machine overlays line counting. main := clang_main & newline; }%% %% write data noprefix; // 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( ) { curLine = 1; %% write 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( char* _data, int _len ) { char *p = _data; char *pe = _data + _len; char *eof = pe; %% write exec; } // 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( ) { if ( cs == error ) return -1; if ( cs >= first_final ) return 1; return 0; } } static const int BUFSIZE = 1024; void test( char buf[] ) { CLang scanner = new CLang(); scanner.init(); scanner.execute( buf.ptr, buf.length ); if ( scanner.finish() > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); return 0; } int main() { test( "999 0xaAFF99 99.99 /*\n" "*/ 'lksdj' //\n" "\"\n" "\n" "literal\n" "\n" "\n" "\"0x00aba foobardd.ddsf 0x0.9\n" ); test( "wordwithnum00asdf\n" "000wordfollowsnum,makes new symbol\n" "\n" "finishing early /* unfinished ...\n" ); test( "/*\n" " * Copyright\n" " */\n" "\n" "/* Aapl.\n" " */\n" " \n" "#define _AAPL_RESIZE_H\n" "\n" "#include \n" "\n" "#ifdef AAPL_NAMESPACE\n" "namespace Aapl {\n" "#endif\n" "#define LIN_DEFAULT_STEP 256\n" "#define EXPN_UP( existing, needed ) \\\n" " need > eng ? (ned<<1) : eing\n" " \n" "\n" "/*@}*/\n" "#undef EXPN_UP\n" "#ifdef AAPL_NAMESPACE\n" "#endif /* _AAPL_RESIZE_H */\n" ); return 0; } /+ _____OUTPUT_____ int(1): 999 hex(1): 0xaAFF99 float(1): 99.99 literal(2): lksdj literal(8): literal hex(8): 0x00aba ident(8): foobardd symbol(8): . ident(8): ddsf hex(8): 0x0 symbol(8): . int(8): 9 ACCEPT ident(1): wordwithnum00asdf int(2): 000 ident(2): wordfollowsnum symbol(2): , ident(2): makes ident(2): new ident(2): symbol ident(4): finishing ident(4): early FAIL symbol(8): # ident(8): define ident(8): _AAPL_RESIZE_H symbol(10): # ident(10): include symbol(10): < ident(10): assert symbol(10): . ident(10): h symbol(10): > symbol(12): # ident(12): ifdef ident(12): AAPL_NAMESPACE ident(13): namespace ident(13): Aapl symbol(13): { symbol(14): # ident(14): endif symbol(15): # ident(15): define ident(15): LIN_DEFAULT_STEP int(15): 256 symbol(16): # ident(16): define ident(16): EXPN_UP symbol(16): ( ident(16): existing symbol(16): , ident(16): needed symbol(16): ) symbol(16): \ ident(17): need symbol(17): > ident(17): eng symbol(17): ? symbol(17): ( ident(17): ned symbol(17): < symbol(17): < int(17): 1 symbol(17): ) symbol(17): : ident(17): eing symbol(21): # ident(21): undef ident(21): EXPN_UP symbol(22): # ident(22): ifdef ident(22): AAPL_NAMESPACE symbol(23): # ident(23): endif ACCEPT ++++++++++++++++/ ragel-6.10/test/export2.rl0000664000175000017500000000151013065111230012363 00000000000000/* * @LANG: java */ class export2 { %%{ machine test; export c1 = 'c'; export c2 = 'z'; export c3 = 't'; commands := ( c1 . digit* '\n' @{ System.out.println( "c1" );} | c2 . alpha* '\n' @{ System.out.println( "c2" );}| c3 . '.'* '\n' @{ System.out.println( "c3" );} )*; other := any*; }%% %% write exports; %% write data; static void test( char data[] ) { int cs = test_en_commands, p = 0, pe = data.length; int top; %% write init nocs; %% write exec; if ( cs >= test_first_final ) System.out.println( "ACCEPT" ); else System.out.println( "FAIL" ); } public static void main( String args[] ) { char data[] = { test_ex_c1, '1', '2', '\n', test_ex_c2, 'a', 'b', '\n', test_ex_c3, '.', '.', '\n', }; test( data ); } } /* _____OUTPUT_____ c1 c2 c3 ACCEPT */ ragel-6.10/test/eofact.h0000664000175000017500000000011113065111230012027 00000000000000#ifndef _EOFACT_H #define _EOFACT_H struct eofact { int cs; }; #endif ragel-6.10/test/erract3.rl0000664000175000017500000000252013065111230012325 00000000000000/* * @LANG: c */ #include #define IDENT_BUFLEN 256 struct erract { int cs; }; %%{ machine erract; variable cs fsm->cs; # The data that is to go into the fsm structure. action hello_fails { printf("hello fails\n");} newline = ( any | '\n' @{printf("newline\n");} )*; hello = 'hello\n'* $lerr hello_fails @eof hello_fails; main := newline | hello; }%% %% write data; void erract_init( struct erract *fsm ) { %% write init; } void erract_execute( struct erract *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; const char *eof = pe; %% write exec; } int erract_finish( struct erract *fsm ) { if ( fsm->cs == erract_error ) return -1; else if ( fsm->cs >= erract_first_final ) return 1; return 0; } #include #include struct erract fsm; void test( char *buf ) { int len = strlen(buf); erract_init( &fsm ); erract_execute( &fsm, buf, len ); if ( erract_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "hello\n" "hello\n" "hello\n" ); test( "hello\n" "hello\n" "hello there\n" ); test( "hello\n" "hello\n" "he" ); test( "" ); return 0; } #ifdef _____OUTPUT_____ newline newline newline ACCEPT newline newline hello fails newline ACCEPT newline newline hello fails ACCEPT ACCEPT #endif ragel-6.10/test/cond4.rl0000664000175000017500000000147013065111230011774 00000000000000/* * @LANG: c++ */ #include #include using std::cout; using std::endl; %%{ machine foo; action c1 {(cout << "c1 ", true)} action c2 {(cout << "c2 ", true)} action c3 {(cout << "c3 ", true)} action c4 {(cout << "c4 ", true)} main := ( 10 .. 60 when c1 | 20 .. 40 when c2 | 30 .. 50 when c3 | 32 .. 38 when c4 | 0 .. 70 )* ${cout << "char: " << (int)*p << endl;}; }%% %% write data noerror nofinal; void test( char *str ) { int len = strlen( str ); int cs = foo_start; char *p = str, *pe = str+len; %% write exec; } char data[] = { 5, 15, 25, 31, 35, 39, 45, 55, 65, 0 }; int main() { test( data ); return 0; } #ifdef _____OUTPUT_____ char: 5 c1 char: 15 c1 c2 char: 25 c1 c2 c3 char: 31 c1 c2 c3 c4 char: 35 c1 c2 c3 char: 39 c1 c3 char: 45 c1 char: 55 char: 65 #endif ragel-6.10/test/scan3.rl0000664000175000017500000000066313065111230011777 00000000000000/* * @LANG: indep */ ptr ts; ptr te; int act; int token; %% %%{ machine scanner; # Warning: changing the patterns or the input string will affect the # coverage of the scanner action types. main := |* 'a' => { prints "pat1\n"; }; 'b' => { prints "pat2\n"; }; [ab] any* => { prints "pat3\n"; }; *|; }%% /* _____INPUT_____ "ab89" _____INPUT_____ */ /* _____OUTPUT_____ pat3 ACCEPT _____OUTPUT_____ */ ragel-6.10/test/export3.rl0000664000175000017500000000123013065111230012363 00000000000000# # @LANG: ruby # %%{ machine test; export c1 = 'c'; export c2 = 'z'; export c3 = 't'; commands := ( c1 . digit* '\n' @{ puts "c1"; } | c2 . alpha* '\n' @{ puts "c2"; }| c3 . '.'* '\n' @{ puts "c3"; } )*; other := any*; }%% %% write exports; %% write data; def run_machine( data ) p = 0; pe = data.length cs = test_en_commands val = 0; neg = false; %% write init nocs; %% write exec; if cs >= test_first_final puts "ACCEPT" else puts "FAIL" end end inp = [ test_ex_c1, ?1, ?2, ?\n, test_ex_c2, ?a, ?b, ?\n, test_ex_c3, ?., ?., ?\n ] run_machine( inp ); =begin _____OUTPUT_____ c1 c2 c3 ACCEPT =end _____OUTPUT_____ ragel-6.10/test/element3.rl0000664000175000017500000000475613065111230012513 00000000000000/* * @LANG: obj-c */ #include #include struct LangEl { int key; char *name; }; @interface Fsm : Object { @public 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. - (int) initFsm; // 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. - (int) executeWithData:( struct LangEl *)data len:(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; @end; @implementation Fsm %%{ machine Fsm; alphtype int; getkey fpc->key; action a1 {} action a2 {} action a3 {} main := ( 1 2* 3 ) ${printf("%s\n", fpc->name);} %/{printf("accept\n");}; }%% %% write data; - (int) initFsm; { %% write init; return 0; } - (int) executeWithData:( struct LangEl *)_data len:(int)_len; { struct LangEl *p = _data; struct LangEl *pe = _data + _len; struct LangEl *eof = pe; %% write exec; if ( self->cs == Fsm_error ) return -1; return ( self->cs >= Fsm_first_final ) ? 1 : 0; } - (int) finish; { if ( self->cs == Fsm_error ) return -1; return ( self->cs >= Fsm_first_final ) ? 1 : 0; } @end int main() { static Fsm *fsm; static struct LangEl lel[] = { {1, "one"}, {2, "two-a"}, {2, "two-b"}, {2, "two-c"}, {3, "three"} }; fsm = [[Fsm alloc] init]; [fsm initFsm]; [fsm executeWithData:lel len:5]; [fsm finish]; return 0; } @interface Fsm2 : Object { // The current state may be read and written to from outside of the // machine. From within action code, curs is -1 and writing to it has no // effect. @public int cs; @protected } // 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. - (int) executeWithElements:(int) elements length:(unsigned)length; @end @implementation Fsm2 - (int) executeWithElements:(int)elements length:(unsigned)length; { return 0; } @end #ifdef _____OUTPUT_____ one two-a two-b two-c three accept #endif ragel-6.10/test/mailbox1.h0000664000175000017500000000164113065111230012313 00000000000000#ifndef _MAILBOX1_H #define _MAILBOX1_H #include #include #include "vector.h" struct MBox { int cs; Vector headName; Vector headContent; // 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( ); }; #endif ragel-6.10/test/atoi2.rl0000664000175000017500000000171613065111230012006 00000000000000/* * @LANG: indep * This implementes an atoi machine using the statechart paradigm. */ bool neg; int val; %% val = 0; neg = false; %%{ machine StateChart; action begin { neg = false; val = 0; } action see_neg { neg = true; } action add_digit { val = val * 10 + (fc - 48); } action finish { if ( neg ) val = -1 * val; } atoi = ( start: ( '-' @see_neg ->om_num | '+' ->om_num | [0-9] @add_digit ->more_nums ), # One or more nums. om_num: ( [0-9] @add_digit ->more_nums ), # Zero ore more nums. more_nums: ( [0-9] @add_digit ->more_nums | '' -> final ) ) >begin %finish; action oneof { printi val; prints "\n"; } main := ( atoi '\n' @oneof )*; }%% /* _____INPUT_____ "1\n" "12\n" "222222\n" "+2123\n" "213 3213\n" "-12321\n" "--123\n" "-99\n" " -3000\n" _____INPUT_____ */ /* _____OUTPUT_____ 1 ACCEPT 12 ACCEPT 222222 ACCEPT 2123 ACCEPT FAIL -12321 ACCEPT FAIL -99 ACCEPT FAIL _____OUTPUT_____ */ ragel-6.10/test/erract6.rl0000664000175000017500000000207313065111230012333 00000000000000/* * @LANG: c */ /* * Test of a transition going to the error state. */ #include #define BUFSIZE 2048 struct errintrans { int cs; }; %%{ machine errintrans; variable cs fsm->cs; char = any - (digit | '\n'); line = char* "\n"; main := line+; }%% %% write data; void errintrans_init( struct errintrans *fsm ) { %% write init; } void errintrans_execute( struct errintrans *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int errintrans_finish( struct errintrans *fsm ) { if ( fsm->cs == errintrans_error ) return -1; if ( fsm->cs >= errintrans_first_final ) return 1; return 0; } struct errintrans fsm; #include void test( char *buf ) { int len = strlen( buf ); errintrans_init( &fsm ); errintrans_execute( &fsm, buf, len ); if ( errintrans_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "good, does not have numbers\n" ); test( "bad, has numbers 666\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT FAIL #endif ragel-6.10/test/cppscan4.rl0000664000175000017500000001773313065111230012511 00000000000000/* * @LANG: d */ module cppscan; import std.c.stdio; import std.string; const int BUFSIZE = 2048; const int TK_Dlit = 192; const int TK_Slit = 193; const int TK_Float = 194; const int TK_Id = 195; const int TK_NameSep = 197; const int TK_Arrow = 211; const int TK_PlusPlus = 212; const int TK_MinusMinus = 213; const int TK_ArrowStar = 214; const int TK_DotStar = 215; const int TK_ShiftLeft = 216; const int TK_ShiftRight = 217; const int TK_IntegerDecimal = 218; const int TK_IntegerOctal = 219; const int TK_IntegerHex = 220; const int TK_EqualsEquals = 223; const int TK_NotEquals = 224; const int TK_AndAnd = 225; const int TK_OrOr = 226; const int TK_MultAssign = 227; const int TK_DivAssign = 228; const int TK_PercentAssign = 229; const int TK_PlusAssign = 230; const int TK_MinusAssign = 231; const int TK_AmpAssign = 232; const int TK_CaretAssign = 233; const int TK_BarAssign = 234; const int TK_DotDotDot = 240; class Scanner { int line, col; int tokStart; int inlineDepth; int count; char[] tokBuf; char[] nonTokBuf; void pass(char c) { nonTokBuf ~= c; } void buf(char c) { tokBuf ~= c; } void token( int id ) { /* Leader. */ if ( nonTokBuf.length > 0 ) { printf("%.*s", nonTokBuf); nonTokBuf = ""; } /* Token data. */ printf("<%d>%.*s", id, tokBuf); tokBuf = ""; } int cs, stack, top; %%{ machine Scanner; action pass { pass(fc); } action buf { buf(fc); } action emit_slit { token( TK_Slit ); } action emit_dlit { token( TK_Dlit ); } action emit_id { token( TK_Id ); } action emit_integer_decimal { token( TK_IntegerDecimal ); } action emit_integer_octal { token( TK_IntegerOctal ); } action emit_integer_hex { token( TK_IntegerHex ); } action emit_float { token( TK_Float ); } action emit_symbol { token( tokBuf[0] ); } action tokst { tokStart = col; } # Single and double literals. slit = ( 'L'? ( "'" ( [^'\\\n] | /\\./ )* "'" ) $buf ) >tokst %emit_slit; dlit = ( 'L'? ( '"' ( [^"\\\n] | /\\./ )* '"' ) $buf ) >tokst %emit_dlit; # Identifiers id = ( [a-zA-Z_] [a-zA-Z0-9_]* ) >tokst $buf %emit_id; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; float = ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) >tokst $buf %emit_float; # Integer decimal. Leading part buffered by float. integer_decimal = ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} $buf ) %emit_integer_decimal; # Integer octal. Leading part buffered by float. integer_octal = ( '0' [0-9]+ [ulUL]{0,2} $buf ) %emit_integer_octal; # Integer hex. Leading 0 buffered by float. integer_hex = ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) $buf ) %emit_integer_hex; # Only buffer the second item, first buffered by symbol. */ namesep = '::' @buf %{token( TK_NameSep );}; deqs = '==' @buf %{token( TK_EqualsEquals );}; neqs = '!=' @buf %{token( TK_NotEquals );}; and_and = '&&' @buf %{token( TK_AndAnd );}; or_or = '||' @buf %{token( TK_OrOr );}; mult_assign = '*=' @buf %{token( TK_MultAssign );}; percent_assign = '%=' @buf %{token( TK_PercentAssign );}; plus_assign = '+=' @buf %{token( TK_PlusAssign );}; minus_assign = '-=' @buf %{token( TK_MinusAssign );}; amp_assign = '&=' @buf %{token( TK_AmpAssign );}; caret_assign = '^=' @buf %{token( TK_CaretAssign );}; bar_assign = '|=' @buf %{token( TK_BarAssign );}; plus_plus = '++' @buf %{token( TK_PlusPlus );}; minus_minus = '--' @buf %{token( TK_MinusMinus );}; arrow = '->' @buf %{token( TK_Arrow );}; arrow_star = '->*' @buf %{token( TK_ArrowStar );}; dot_star = '.*' @buf %{token( TK_DotStar );}; # Buffer both items. * div_assign = '/=' @{buf('/');buf(fc);} %{token( TK_DivAssign );}; # Double dot is sent as two dots. dot_dot = '..' %{token('.'); buf('.'); token('.');}; # Three char compounds, first item already buffered. */ dot_dot_dot = '...' %{buf('.'); buf('.'); token( TK_DotDotDot );}; # All compunds compound = namesep | deqs | neqs | and_and | or_or | mult_assign | div_assign | percent_assign | plus_assign | minus_assign | amp_assign | caret_assign | bar_assign | plus_plus | minus_minus | arrow | arrow_star | dot_star | dot_dot | dot_dot_dot; # Single char symbols. symbol = ( punct - [./_"'] ) >tokst $buf %emit_symbol | # Do not immediately buffer slash, may be start of comment. '/' >tokst %{ buf('/'); token( '/' ); } | # Dot covered by float. '.' %emit_symbol; # Comments and whitespace. commc = '/*' @{pass('/'); pass('*');} ( any* $0 '*/' @1 ) $pass; commcc = '//' @{pass('/'); pass('/');} ( any* $0 '\n' @1 ) $pass; whitespace = ( any - ( 0 | 33..126 ) )+ $pass; action onEOFChar { /* On EOF char, write out the non token buffer. */ printf("%.*s", nonTokBuf); nonTokBuf = ""; } # Using 0 as eof. If seeingAs a result all null characters get ignored. EOF = 0 @onEOFChar; # All outside code tokens. tokens = ( id | slit | dlit | float | integer_decimal | integer_octal | integer_hex | compound | symbol ); nontok = ( commc | commcc | whitespace | EOF ); position = ( '\n' @{ line += 1; col = 1; } | [^\n] @{ col += 1; } )*; main := ( ( tokens | nontok )** ) & position; }%% %% write data noprefix; void init( ) { /* A count of the number of characters in * a token. Used for % sequences. */ count = 0; line = 1; col = 1; %% write init; return 1; } int execute( char* _data, int _len ) { char *p = _data; char *pe = _data + _len; char *eof = null; %% write exec; if ( cs == error ) return -1; if ( cs >= first_final ) return 1; return 0; } // 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( ) { if ( cs == error ) return -1; if ( cs >= first_final ) return 1; return 0; } }; void test(char[] buf) { Scanner scanner = new Scanner(); scanner.init(); scanner.execute( buf.ptr, buf.length ); /* The last token is ignored (because there is no next token). Send * trailing null to force the last token into whitespace. */ char eof_char = 0; if ( scanner.execute( &eof_char, 1 ) <= 0 ) { fprintf(stderr, "cppscan: scan failed\n"); } } int main() { test( "/*\n" " * Copyright \n" " */\n" "\n" "RedTransAp *RedFsmAp::reduceTrans( TransAp *trans )\n" "{\n" " RedAction *action = 0;\n" " if ( trans->actionTable.length() > 0 ) {\n" " if ( actionMap.insert( trans->actionTable, &action ) )\n" " action->id = nextActionId++;\n" " }\n" " \n" " RedStateAp *targ = (RedStateAp*)trans->toState;\n" " if ( action == 0 ) {\n" " delete trans;\n" " return 0;\n" " }\n" "\n" " trans->~TransAp();\n" " inDict = new(trans) RedTransAp( targ, action, nextTransId++ );\n" " transSet.insert( inDict );\n" "}\n" ); test( "->*\n" ".*\n" "/*\"*/\n" "\"/*\"\n" "L'\"'\n" "L\"'\"\n" ); return 0; } /+ _____OUTPUT_____ /* * Copyright */ <195>RedTransAp <42>*<195>RedFsmAp<197>::<195>reduceTrans<40>( <195>TransAp <42>*<195>trans <41>) <123>{ <195>RedAction <42>*<195>action <61>= <218>0<59>; <195>if <40>( <195>trans<211>-><195>actionTable<46>.<195>length<40>(<41>) <62>> <218>0 <41>) <123>{ <195>if <40>( <195>actionMap<46>.<195>insert<40>( <195>trans<211>-><195>actionTable<44>, <38>&<195>action <41>) <41>) <195>action<211>-><195>id <61>= <195>nextActionId<212>++<59>; <125>} <195>RedStateAp <42>*<195>targ <61>= <40>(<195>RedStateAp<42>*<41>)<195>trans<211>-><195>toState<59>; <195>if <40>( <195>action <223>== <218>0 <41>) <123>{ <195>delete <195>trans<59>; <195>return <218>0<59>; <125>} <195>trans<211>-><126>~<195>TransAp<40>(<41>)<59>; <195>inDict <61>= <195>new<40>(<195>trans<41>) <195>RedTransAp<40>( <195>targ<44>, <195>action<44>, <195>nextTransId<212>++ <41>)<59>; <195>transSet<46>.<195>insert<40>( <195>inDict <41>)<59>; <125>} <214>->* <215>.* /*"*/ <192>"/*" <193>L'"' <192>L"'" +++++++++++++++++/ ragel-6.10/test/recdescent3.rl0000664000175000017500000000337213065111230013172 00000000000000# # @LANG: ruby # %%{ machine recdescent3; prepush { if top == stack_size print( "growing stack\n" ); stack_size = top * 2; # Don't actually bother to resize here, but we do print messages. # stack = (int*)realloc( stack, sizeof(int)*stack_size ); end } postpop { if stack_size > (top * 4) print( "shrinking stack\n" ); stack_size = top * 2; # Don't actually bother to resize here, but we do print messages. # stack = (int*)realloc( stack, sizeof(int)*stack_size ); end } action item_start { item = p; } action item_finish { print( "item: " ); print( data[item..p-1] ); print( "\n" ); } action call_main { print( "calling main\n" ); fcall main; } action return_main { if top == 0 print( "STRAY CLOSE\n" ); fbreak; end print( "returning from main\n" ); fhold; fret; } id = [a-zA-Z_]+; number = [0-9]+; ws = [ \t\n]+; main := ( ws | ( number | id ) >item_start %item_finish | '{' @call_main '}' | '}' @return_main )**; }%% %% write data; def run_machine( data ) item = 0; p = 0; pe = data.length; eof = pe; cs = 0; stack = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; stack_size = 1; top = 0; %% write init; %% write exec; if cs == recdescent3_error puts "SCANNER_ERROR" end end inp = [ "88 foo { 99 {{{{}}}}{ } }", "76 } sadf" ] inp.each { |str| run_machine(str) } =begin _____OUTPUT_____ item: 88 item: foo calling main item: 99 calling main growing stack calling main growing stack calling main calling main growing stack returning from main returning from main returning from main returning from main shrinking stack calling main returning from main returning from main shrinking stack item: 76 STRAY CLOSE =end _____OUTPUT_____ ragel-6.10/test/forder3.rl0000664000175000017500000000275013065111230012333 00000000000000/* * @LANG: c */ #include #include struct forder { int cs; }; %%{ machine forder; variable cs fsm->cs; m1 = ( "" %{printf("enter m1 aa\n");} | 'aa'* >{printf("enter m1 aa\n");} %{printf("leave m1 aa\n");} ) 'b' @{printf("through m1 b\n");} . 'b'* . 'a'*; m2 = 'bbb'* 'aa'*; main := ( m1 %{printf("accept m1\n");} | "" %{printf("enter m2\n");} | m2 >{printf("enter m2\n");} %{printf("accept m2\n");} ) . '\n'; }%% %% write data; void forder_init( struct forder *fsm ) { %% write init; } void forder_execute( struct forder *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int forder_finish( struct forder *fsm ) { if ( fsm->cs == forder_error ) return -1; if ( fsm->cs >= forder_first_final ) return 1; return 0; } struct forder fsm; void test( char *buf ) { int len = strlen( buf ); forder_init( &fsm ); forder_execute( &fsm, buf, len ); if ( forder_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "aaaaaabbbaa\n" ); test( "\n" ); test( "bbbbbbaaaaaaa\n" ); test( "bbbbbbaaaaaa\n" ); test( "aaaaa\n" ); return 0; } #ifdef _____OUTPUT_____ enter m1 aa enter m2 leave m1 aa through m1 b accept m1 ACCEPT enter m2 enter m2 accept m2 ACCEPT enter m1 aa enter m1 aa leave m1 aa through m1 b enter m2 accept m1 ACCEPT enter m1 aa enter m1 aa leave m1 aa through m1 b enter m2 accept m1 accept m2 ACCEPT enter m1 aa enter m2 FAIL #endif ragel-6.10/test/erract1.rl0000664000175000017500000000460413065111230012330 00000000000000/* * @LANG: c++ */ /* * Test error actions. */ #include #include #include using namespace std; struct ErrAct { 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. int 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. int 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 ErrAct; action expect_digit_plus_minus { printf(" DIGIT PLUS MINUS\n"); } action expect_digit { printf(" DIGIT\n"); } action expect_digit_decimal { printf(" DIGIT DECIMAL\n"); } float = ( ( [\-+] >err expect_digit_plus_minus %err expect_digit | "" ) ( [0-9] [0-9]* $err expect_digit_decimal ) ( '.' [0-9]+ $err expect_digit )? ); main := float '\n'; }%% %% write data; int ErrAct::init( ) { %% write init; return 0; } int ErrAct::execute( const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; const char *eof = pe; %% write exec; if ( cs == ErrAct_error ) return -1; if ( cs >= ErrAct_first_final ) return 1; return 0; } int ErrAct::finish( ) { if ( cs == ErrAct_error ) return -1; if ( cs >= ErrAct_first_final ) return 1; return 0; } #define BUFSIZE 1024 void test( const char *buf ) { ErrAct errAct; errAct.init(); errAct.execute( buf, strlen(buf) ); if ( errAct.finish() > 0 ) cout << "ACCEPT" << endl; else cout << "FAIL" << endl; } int main() { test( "1\n" ); test( "+1\n" ); test( "-1\n" ); test( "1.1\n" ); test( "+1.1\n" ); test( "-1.1\n" ); test( "a\n" ); test( "-\n" ); test( "+\n" ); test( "-a\n" ); test( "+b\n" ); test( "1.\n" ); test( "1d\n" ); test( "1.d\n" ); test( "1.1d\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT ACCEPT ACCEPT ACCEPT ACCEPT DIGIT PLUS MINUS FAIL DIGIT FAIL DIGIT FAIL DIGIT FAIL DIGIT FAIL DIGIT FAIL DIGIT DECIMAL FAIL DIGIT FAIL DIGIT FAIL #endif ragel-6.10/test/langtrans_ruby.sh0000775000175000017500000000317413065111230014022 00000000000000#!/bin/bash # file=$1 [ -f $file ] || exit 1 # Get the machine name. machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' \ $file | tr '[A-Z]' '[a-z]'` # Make a temporary version of the test case using the Ruby language translations. sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_ruby.txl > $file.pr # Begin writing out the test case. cat << EOF # # @LANG: ruby # @GENERATED: yes EOF grep '@ALLOW_GENFLAGS:' $file | sed 's/^ *\*/#/' | sed 's/-G.//g' grep '@ALLOW_MINFLAGS:' $file | sed 's/^ *\*/#/' cat << EOF # EOF # Write out the machine specification. sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr # Write out the init and execute routines. cat << EOF %% write data; def run_machine( data ) p = 0 pe = data.length eof = data.length cs = 0; EOF # Write the data declarations sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr # Write the data initializations sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr cat << EOF %% write init; %% write exec; if cs >= ${machine}_first_final puts "ACCEPT" else puts "FAIL" end end EOF # Write out the test data. sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' BEGIN { print " inp = [" } { print " " $0 "," } END { print " ]" print "" print " inplen = " NR ";" }' # Write out the main routine. cat << EOF inp.each { |str| run_machine(str.unpack("c*")) } EOF # Write out the expected output. echo "=begin _____OUTPUT_____" sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//{/_____OUTPUT_____/d;p;};' $file echo "=end _____OUTPUT_____" # Don't need this language-specific file anymore. rm $file.pr ragel-6.10/test/strings2.rl0000664000175000017500000011434613065111230012547 00000000000000/* * @LANG: c * @ALLOW_GENFLAGS: -T0 -T1 -F0 -F1 * @ALLOW_MINFLAGS: -n -m -l * * Test works with split code gen. */ #include #include #include "strings2.h" %%{ machine strs; variable cs fsm->cs; main := "/lib/ld-linux.so.2\n" | "libstdc++-libc6.2-2.so.3\n" | "cerr\n" | "__cp_push_exception\n" | "_DYNAMIC\n" | "endl__FR7ostream\n" | "__ls__7ostreamc\n" | "_._9exception\n" | "__vt_9bad_alloc\n" | "__rtti_user\n" | "__ls__7ostreamPFR7ostream_R7ostream\n" | "__rtti_si\n" | "_init\n" | "bad__C3ios\n" | "__throw\n" | "__ls__7ostreamPCc\n" | "__deregister_frame_info\n" | "terminate__Fv\n" | "__ls__7ostreamb\n" | "__ls__7ostreami\n" | "__8ofstreamiPCcii\n" | "__builtin_vec_new\n" | "_fini\n" | "__9exception\n" | "__builtin_vec_delete\n" | "_GLOBAL_OFFSET_TABLE_\n" | "__vt_9exception\n" | "__nw__FUiPv\n" | "_._9bad_alloc\n" | "__builtin_delete\n" | "__builtin_new\n" | "cout\n" | "__register_frame_info\n" | "__eh_alloc\n" | "__gmon_start__\n" | "libm.so.6\n" | "libc.so.6\n" | "strcpy\n" | "stdout\n" | "memmove\n" | "memcpy\n" | "malloc\n" | "strtoul\n" | "fprintf\n" | "stdin\n" | "ferror\n" | "strncpy\n" | "strcasecmp\n" | "realloc\n" | "_IO_getc\n" | "fread\n" | "memset\n" | "clearerr\n" | "__assert_fail\n" | "strcmp\n" | "stderr\n" | "fwrite\n" | "__errno_location\n" | "exit\n" | "fopen\n" | "atoi\n" | "_IO_stdin_used\n" | "__libc_start_main\n" | "strlen\n" | "free\n" | "_edata\n" | "__bss_start\n" | "_end\n" | "GLIBC_2.1\n" | "GLIBC_2.0\n" | "PTRh\n" | "QVhL\n" | " Write output to .\n" | " -s Print stats on the compiled fsm.\n" | " -f Dump the final fsm.\n" | "fsm minimization:\n" | " -n No minimization (default).\n" | " -m Find the minimal fsm accepting the language.\n" | "generated code language:\n" | " -c Generate c code (default).\n" | " -C Generate c++ code.\n" | "generated code style:\n" | " -T0 Generate a table driven fsm (default).\n" | " -T1 Generate a faster table driven fsm.\n" | " -S0 Generate a switch driven fsm.\n" | " -G0 Generate a goto driven fsm.\n" | " -G1 Generate a faster goto driven fsm.\n" | " -G2 Generate a really fast goto driven fsm.\n" | "char * FileNameFromStem(char *, char *)\n" | "main.cpp\n" | "len > 0\n" | "main\n" | "ragel: main graph not defined\n" | "graph states: \n" | "graph transitions: \n" | "machine states: \n" | "machine functions: \n" | "function array: \n" | "T:S:G:Cco:senmabjkfhH?-:\n" | "ragel: zero length output file name given\n" | "ragel: output file already given\n" | "ragel: invalid param specified (try -h for a list of options)\n" | "help\n" | "ragel: zero length input file name given\n" | "ragel: input file already given\n" | "ragel: warning: -e given but minimization is not enabled\n" | "ragel: no input file (try -h for a list of options)\n" | " for reading\n" | "ragel: could not open \n" | " for writing\n" | "ragel: error opening \n" | " * Parts of this file are copied from Ragel source covered by the GNU\n" | " * GPL. As a special exception, you may use the parts of this file copied\n" | " * from Ragel source without restriction. The remainder is derived from\n" | "bad_alloc\n" | "%s:%i: unterminated literal\n" | "%s:%i: unterminated comment\n" | "%s:%i: bad character in literal\n" | "fatal flex scanner internal error--no action found\n" | "fatal flex scanner internal error--end of buffer missed\n" | "fatal error - scanner input buffer overflow\n" | "input in flex scanner failed\n" | "out of dynamic memory in yy_create_buffer()\n" | "out of dynamic memory in yy_scan_buffer()\n" | "out of dynamic memory in yy_scan_bytes()\n" | "bad buffer in yy_scan_bytes()\n" | "bad_alloc\n" | "%s:%i: warning: range gives null fsm\n" | "%s:%i: warning: literal used in range is not of length 1, using 0x%x\n" | "%s:%i: warning: overflow in byte constant\n" | "parse error\n" | "parser stack overflow\n" | "%s:%i: %s\n" | "bad_alloc\n" | "extend\n" | "ascii\n" | "alpha\n" | "digit\n" | "alnum\n" | "lower\n" | "upper\n" | "cntrl\n" | "graph\n" | "print\n" | "punct\n" | "space\n" | "xdigit\n" | "struct Fsm * FactorWithAugNode::Walk()\n" | "parsetree.cpp\n" | "false\n" | "bad_alloc\n" | "xx []()\n" | " df \n" | "StartState: \n" | "Final States:\n" | "void FsmGraph::AttachStates(State *, State *, Trans *, FsmKeyType, int)\n" | "rlfsm/fsmattach.cpp\n" | "trans->toState == __null\n" | "trans->fromState == __null\n" | "void FsmGraph::DetachStates(State *, State *, Trans *, FsmKeyType, int)\n" | "trans->toState == to\n" | "trans->fromState == from\n" | "inTel != __null\n" | "void Vector,ResizeExpn>::setAs(const Vector,ResizeExpn> &)\n" | "aapl/vectcommon.h\n" | "&v != this\n" | "void FsmGraph::ChangeRangeLowerKey(Trans *, int, int)\n" | "inRangeEl != __null\n" | "void FsmGraph::IsolateStartState()\n" | "rlfsm/fsmgraph.cpp\n" | "md.stateDict.nodeCount == 0\n" | "md.stfil.listLength == 0\n" | "struct State * FsmGraph::DetachState(State *)\n" | "fromTel != __null\n" | "struct Trans * FsmGraph::AttachStates(State *, State *, FsmKeyType, int, int)\n" | "outTel != __null\n" | "outTel1 != __null\n" | "from->defOutTrans == __null\n" | "void FsmGraph::VerifyOutFuncs()\n" | "state->outTransFuncTable.tableLength == 0\n" | "!state->isOutPriorSet\n" | "state->outPriority == 0\n" | "void FsmGraph::VerifyIntegrity()\n" | "rlfsm/fsmbase.cpp\n" | "outIt.trans->fromState == state\n" | "inIt.trans->toState == state\n" | "static int FsmTrans >::ComparePartPtr(FsmTrans > *, FsmTrans > *)\n" | "rlfsm/fsmstate.cpp\n" | "false\n" | "void FsmGraph::InTransMove(State *, State *)\n" | "dest != src\n" | "static bool FsmTrans >::ShouldMarkPtr(MarkIndex &, FsmTrans > *, FsmTrans > *)\n" | "bad_alloc\n" | "10FsmCodeGen\n" | "bad_alloc\n" | " case \n" | "break;}\n" | "unsigned char\n" | "unsigned short\n" | "unsigned int\n" | "{0, \n" | "/* Forward dec state for the transition structure. */\n" | "struct \n" | "StateStruct;\n" | "/* A single transition. */\n" | "struct \n" | "TransStruct\n" | " struct \n" | "StateStruct *toState;\n" | " int *funcs;\n" | "typedef struct \n" | "TransStruct \n" | "Trans;\n" | "/* A single state. */\n" | "struct \n" | "StateStruct\n" | " int lowIndex;\n" | " int highIndex;\n" | " void *transIndex;\n" | " unsigned int dflIndex;\n" | " int *outFuncs;\n" | " int isFinState;\n" | "typedef struct \n" | "StateStruct \n" | "State;\n" | "/* Only non-static data: current state. */\n" | "struct \n" | "Struct\n" | "State *curState;\n" | " int accept;\n" | "typedef struct \n" | "Struct \n" | "/* Init the fsm. */\n" | "void \n" | "Init( \n" | " *fsm );\n" | "/* Execute some chunk of data. */\n" | "void \n" | "Execute( \n" | " *fsm, char *data, int dlen );\n" | "/* Indicate to the fsm tha there is no more data. */\n" | "void \n" | "Finish( \n" | " *fsm );\n" | "/* Did the machine accept? */\n" | "int \n" | "Accept( \n" | " *fsm );\n" | "#define f \n" | "#define s \n" | "#define i \n" | "#define t \n" | "/* The array of functions. */\n" | "#if \n" | "static int \n" | "_f[] = {\n" | "#endif\n" | "/* The array of indicies into the transition array. */\n" | "#if \n" | "static \n" | "_i[] = {\n" | "#endif\n" | "/* The aray of states. */\n" | "static \n" | "State \n" | "_s[] = {\n" | "/* The array of transitions. */\n" | "static \n" | "Trans \n" | "_t[] = {\n" | "/* The start state. */\n" | "static \n" | "State *\n" | "_startState = s+\n" | "#undef f\n" | "#undef s\n" | "#undef i\n" | "#undef t\n" | "* Execute functions pointed to by funcs until the null function is found. \n" | "inline static void \n" | "ExecFuncs( \n" | " *fsm, int *funcs, char *p )\n" | " int len = *funcs++;\n" | " while ( len-- > 0 ) {\n" | " switch ( *funcs++ ) {\n" | " * Init the fsm to a runnable state.\n" | "void \n" | " *fsm )\n" | " fsm->curState = \n" | "_startState;\n" | " fsm->accept = 0;\n" | " * Did the fsm accept? \n" | "int \n" | " *fsm )\n" | " return fsm->accept;\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | " *fsm, char *data, int dlen )\n" | " char *p = data;\n" | " int len = dlen;\n" | "State *cs = fsm->curState;\n" | " for ( ; len > 0; p++, len-- ) {\n" | " int c = (unsigned char) *p;\n" | "Trans *trans;\n" | " if ( cs == 0 )\n" | " goto finished;\n" | " /* If the character is within the index bounds then get the\n" | " * transition for it. If it is out of the transition bounds\n" | " * we will use the default transition. */\n" | " if ( cs->lowIndex <= c && c < cs->highIndex ) {\n" | " /* Use the index to look into the transition array. */\n" | " trans = \n" | "_t + \n" | " ((\n" | "*)cs->transIndex)[c - cs->lowIndex];\n" | " else {\n" | " /* Use the default index as the char is out of range. */\n" | " trans = \n" | "_t + cs->dflIndex;\n" | " /* If there are functions for this transition then execute them. */\n" | " if ( trans->funcs != 0 )\n" | "ExecFuncs( fsm, trans->funcs, p );\n" | " /* Move to the new state. */\n" | " cs = trans->toState;\n" | "finished:\n" | " fsm->curState = cs;\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | " *fsm )\n" | "State *cs = fsm->curState;\n" | " if ( cs != 0 && cs->isFinState ) {\n" | " /* If finishing in a final state then execute the\n" | " * out functions for it. (if any). */\n" | " if ( cs->outFuncs != 0 )\n" | "ExecFuncs( fsm, cs->outFuncs, 0 );\n" | " fsm->accept = 1;\n" | " else {\n" | " /* If we are not in a final state then this\n" | " * is an error. Move to the error state. */\n" | " fsm->curState = 0;\n" | "class \n" | "public:\n" | " /* Forward dec state for the transition structure. */\n" | " struct State;\n" | " /* A single transition. */\n" | " struct Trans\n" | " State *toState;\n" | " int *funcs;\n" | " /* A single state. */\n" | " struct State\n" | " int lowIndex;\n" | " int highIndex;\n" | " void *transIndex;\n" | " unsigned int dflIndex;\n" | " int *outFuncs;\n" | " int isFinState;\n" | " /* Constructor. */\n" | " void Init( );\n" | " /* Execute some chunk of data. */\n" | " void Execute( char *data, int dlen );\n" | " /* Indicate to the fsm tha there is no more data. */\n" | " void Finish( );\n" | " /* Did the machine accept? */\n" | " int Accept( );\n" | " State *curState;\n" | " int accept;\n" | " inline void ExecFuncs( int *funcs, char *p );\n" | "/* The array of functions. */\n" | "#if \n" | "::State \n" | "/* The array of trainsitions. */\n" | "static \n" | "::Trans \n" | "/* The start state. */\n" | "static \n" | "::State *\n" | " * Execute functions pointed to by funcs until the null function is found. \n" | "inline void \n" | "::ExecFuncs( int *funcs, char *p )\n" | " int len = *funcs++;\n" | " while ( len-- > 0 ) {\n" | " switch ( *funcs++ ) {\n" | " * Constructor\n" | " Init();\n" | "Init\n" | "void \n" | "::Init( )\n" | " curState = \n" | "_startState;\n" | " accept = 0;\n" | "::Accept( )\n" | " return accept;\n" | "::Execute( char *data, int dlen )\n" | " char *p = data;\n" | " int len = dlen;\n" | " State *cs = curState;\n" | " for ( ; len > 0; p++, len-- ) {\n" | " int c = (unsigned char)*p;\n" | " Trans *trans;\n" | " if ( cs == 0 )\n" | " goto finished;\n" | " /* If the character is within the index bounds then get the\n" | " * transition for it. If it is out of the transition bounds\n" | " * we will use the default transition. */\n" | " if ( cs->lowIndex <= c && c < cs->highIndex ) {\n" | " /* Use the index to look into the transition array. */\n" | " trans = \n" | "_t + cs->dflIndex;\n" | " /* If there are functions for this transition then execute them. */\n" | " if ( trans->funcs != 0 )\n" | " ExecFuncs( trans->funcs, p );\n" | " /* Move to the new state. */\n" | " cs = trans->toState;\n" | "finished:\n" | " curState = cs;\n" | "::Finish( )\n" | " State *cs = curState;\n" | " if ( cs != 0 && cs->isFinState ) {\n" | " /* If finishing in a final state then execute the\n" | " * out functions for it. (if any). */\n" | " if ( cs->outFuncs != 0 )\n" | " ExecFuncs( cs->outFuncs, 0 );\n" | " accept = 1;\n" | " else {\n" | " /* If we are not in a final state then this\n" | " * is an error. Move to the error state. */\n" | " curState = 0;\n" | "10TabCodeGen\n" | "11CTabCodeGen\n" | "12CCTabCodeGen\n" | "10FsmCodeGen\n" | "bad_alloc\n" | " case \n" | " break;\n" | "/* Forward dec state for the transition structure. */\n" | "struct \n" | "StateStruct;\n" | "/* A single transition. */\n" | "struct \n" | "TransStruct\n" | " struct \n" | "StateStruct *toState;\n" | " int funcs;\n" | "typedef struct \n" | "TransStruct \n" | "Trans;\n" | "/* A single state. */\n" | "struct \n" | "StateStruct\n" | " int lowIndex;\n" | " int highIndex;\n" | " void *transIndex;\n" | " int dflIndex;\n" | " int outFuncs;\n" | " int isFinState;\n" | "typedef struct \n" | "StateStruct \n" | "State;\n" | "/* Only non-static data: current state. */\n" | "struct \n" | "Struct\n" | "State *curState;\n" | " int accept;\n" | "typedef struct \n" | "Struct \n" | "/* Init the fsm. */\n" | "void \n" | "Init( \n" | " *fsm );\n" | "/* Execute some chunk of data. */\n" | "void \n" | "Execute( \n" | " *fsm, char *data, int dlen );\n" | "/* Indicate to the fsm tha there is no more data. */\n" | "void \n" | "Finish( \n" | " *fsm );\n" | "/* Did the machine accept? */\n" | "int \n" | "Accept( \n" | " *fsm );\n" | "#define s \n" | "#define i \n" | "#define t \n" | "/* The array of indicies into the transition array. */\n" | "#if \n" | "static \n" | "_i[] = {\n" | "#endif\n" | "/* The aray of states. */\n" | "static \n" | "State \n" | "_s[] = {\n" | "/* The array of trainsitions. */\n" | "static \n" | "Trans \n" | "_t[] = {\n" | "/* The start state. */\n" | "static \n" | "State *\n" | "_startState = s+\n" | "#undef f\n" | "#undef s\n" | "#undef i\n" | "#undef t\n" | "/***************************************************************************\n" | " * Execute functions pointed to by funcs until the null function is found. \n" | "inline static void \n" | "ExecFuncs( \n" | " *fsm, int funcs, char *p )\n" | " switch ( funcs ) {\n" | "/****************************************\n" | "Init\n" | "void \n" | " *fsm )\n" | " fsm->curState = \n" | "_startState;\n" | " fsm->accept = 0;\n" | "/****************************************\n" | "Accept\n" | " * Did the fsm accept? \n" | "int \n" | " *fsm )\n" | " return fsm->accept;\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | " *fsm, char *data, int dlen )\n" | " char *p = data;\n" | " int len = dlen;\n" | "State *cs = fsm->curState;\n" | " for ( ; len > 0; p++, len-- ) {\n" | " int c = (unsigned char)*p;\n" | "Trans *trans;\n" | " if ( cs == 0 )\n" | " goto finished;\n" | " /* If the character is within the index bounds then get the\n" | " * transition for it. If it is out of the transition bounds\n" | " * we will use the default transition. */\n" | " if ( cs->lowIndex <= c && c < cs->highIndex ) {\n" | " /* Use the index to look into the transition array. */\n" | " trans = \n" | "_t + \n" | " ((\n" | "*)cs->transIndex)[c - cs->lowIndex];\n" | " else {\n" | " /* Use the default index as the char is out of range. */\n" | " trans = \n" | "_t + cs->dflIndex;\n" | " /* If there are functions for this transition then execute them. */\n" | " if ( trans->funcs >= 0 )\n" | "ExecFuncs( fsm, trans->funcs, p );\n" | " /* Move to the new state. */\n" | " cs = trans->toState;\n" | "finished:\n" | " fsm->curState = cs;\n" | "/**********************************************************************\n" | "Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | " *fsm )\n" | "State *cs = fsm->curState;\n" | " if ( cs != 0 && cs->isFinState ) {\n" | " /* If finishing in a final state then execute the\n" | " * out functions for it. (if any). */\n" | " if ( cs->outFuncs != 0 )\n" | "ExecFuncs( fsm, cs->outFuncs, 0 );\n" | " fsm->accept = 1;\n" | " else {\n" | " /* If we are not in a final state then this\n" | " * is an error. Move to the error state. */\n" | " fsm->curState = 0;\n" | "class \n" | "public:\n" | " /* Function and index type. */\n" | " typedef int Func;\n" | " /* Forward dec state for the transition structure. */\n" | " struct State;\n" | " /* A single transition. */\n" | " struct Trans\n" | " State *toState;\n" | " int funcs;\n" | " /* A single state. */\n" | " struct State\n" | " int lowIndex;\n" | " int highIndex;\n" | " void *transIndex;\n" | " int dflIndex;\n" | " int outFuncs;\n" | " int isFinState;\n" | " /* Constructor. */\n" | " void Init( );\n" | " /* Execute some chunk of data. */\n" | " void Execute( char *data, int dlen );\n" | " /* Indicate to the fsm tha there is no more data. */\n" | " void Finish( );\n" | " /* Did the machine accept? */\n" | " int Accept( );\n" | " State *curState;\n" | " int accept;\n" | " inline void ExecFuncs( int funcs, char *p );\n" | "::State \n" | "::Trans \n" | "::State *\n" | "/***************************************************************************\n" | " * Execute functions pointed to by funcs until the null function is found. \n" | "inline void \n" | "::ExecFuncs( int funcs, char *p )\n" | " switch ( funcs ) {\n" | "/****************************************\n" | " * Constructor\n" | " Init();\n" | "/****************************************\n" | "::Init( )\n" | " curState = \n" | "_startState;\n" | " accept = 0;\n" | "/****************************************\n" | " * Did the fsm accept? \n" | "int \n" | "::Accept( )\n" | " return accept;\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | "::Execute( char *data, int dlen )\n" | " char *p = data;\n" | " int len = dlen;\n" | " State *cs = curState;\n" | " for ( ; len > 0; p++, len-- ) {\n" | " int c = (unsigned char)*p;\n" | " Trans *trans;\n" | " if ( cs == 0 )\n" | " goto finished;\n" | " /* If the character is within the index bounds then get the\n" | " * transition for it. If it is out of the transition bounds\n" | " * we will use the default transition. */\n" | " if ( cs->lowIndex <= c && c < cs->highIndex ) {\n" | " /* Use the index to look into the transition array. */\n" | " trans = \n" | "_t + cs->dflIndex;\n" | " /* If there are functions for this transition then execute them. */\n" | " if ( trans->funcs != 0 )\n" | " ExecFuncs( trans->funcs, p );\n" | " /* Move to the new state. */\n" | " cs = trans->toState;\n" | "finished:\n" | " curState = cs;\n" | "/**********************************************************************\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | "::Finish( )\n" | " State *cs = curState;\n" | " if ( cs != 0 && cs->isFinState ) {\n" | " /* If finishing in a final state then execute the\n" | " * out functions for it. (if any). */\n" | " if ( cs->outFuncs != 0 )\n" | " ExecFuncs( cs->outFuncs, 0 );\n" | " accept = 1;\n" | " else {\n" | " /* If we are not in a final state then this\n" | " * is an error. Move to the error state. */\n" | " curState = 0;\n" | "11FTabCodeGen\n" | "12CFTabCodeGen\n" | "13CCFTabCodeGen\n" | "bad_alloc\n" | "cs = -1; \n" | "cs = \n" | "break;\n" | " switch( cs ) {\n" | " case \n" | " switch ( c ) {\n" | "case \n" | "default: \n" | " }\n" | " break;\n" | " switch( cs ) {\n" | "accept = 1; \n" | "/* Only non-static data: current state. */\n" | "struct \n" | "Struct\n" | " int curState;\n" | " int accept;\n" | "typedef struct \n" | "Struct \n" | "/* Init the fsm. */\n" | "void \n" | "Init( \n" | " *fsm );\n" | "/* Execute some chunk of data. */\n" | "void \n" | "Execute( \n" | " *fsm, char *data, int dlen );\n" | "/* Indicate to the fsm tha there is no more data. */\n" | "void \n" | "Finish( \n" | " *fsm );\n" | "/* Did the machine accept? */\n" | "int \n" | "Accept( \n" | " *fsm );\n" | "/* The start state. */\n" | "static int \n" | "_startState = \n" | "/****************************************\n" | "Init\n" | "void \n" | " *fsm )\n" | " fsm->curState = \n" | "_startState;\n" | " fsm->accept = 0;\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | " *fsm, char *data, int dlen )\n" | " char *p = data;\n" | " int len = dlen;\n" | " int cs = fsm->curState;\n" | " for ( ; len > 0; p++, len-- ) {\n" | " unsigned char c = (unsigned char)*p;\n" | " fsm->curState = cs;\n" | "/**********************************************************************\n" | "Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | " *fsm )\n" | " int cs = fsm->curState;\n" | " int accept = 0;\n" | " fsm->accept = accept;\n" | "/*******************************************************\n" | "Accept\n" | " * Did the machine accept?\n" | "int \n" | " *fsm )\n" | " return fsm->accept;\n" | "/* Only non-static data: current state. */\n" | "class \n" | "public:\n" | " /* Init the fsm. */\n" | " void Init( );\n" | " /* Execute some chunk of data. */\n" | " void Execute( char *data, int dlen );\n" | " /* Indicate to the fsm tha there is no more data. */\n" | " void Finish( );\n" | " /* Did the machine accept? */\n" | " int Accept( );\n" | " int curState;\n" | " int accept;\n" | " /* The start state. */\n" | " static int startState;\n" | "/* The start state. */\n" | "int \n" | "::startState = \n" | " Init();\n" | "/****************************************\n" | "::Init\n" | "void \n" | "::Init( )\n" | " curState = startState;\n" | " accept = 0;\n" | "::Execute( char *data, int dlen )\n" | " char *p = data;\n" | " int len = dlen;\n" | " int cs = curState;\n" | " for ( ; len > 0; p++, len-- ) {\n" | " unsigned char c = (unsigned char)*p;\n" | " curState = cs;\n" | "/**********************************************************************\n" | "::Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | "::Finish( )\n" | " int cs = curState;\n" | " int accept = 0;\n" | " this->accept = accept;\n" | "/*******************************************************\n" | "::Accept\n" | " * Did the machine accept?\n" | "int \n" | "::Accept( )\n" | " return accept;\n" | "10SelCodeGen\n" | "11CSelCodeGen\n" | "12CCSelCodeGen\n" | "10FsmCodeGen\n" | "bad_alloc\n" | "goto tr\n" | "goto st\n" | "goto err;\n" | " case \n" | "break;}\n" | ": goto st\n" | " case \n" | " default: return;\n" | " goto st\n" | " if ( --len == 0 )\n" | " goto out\n" | " switch( (alph) *++p ) {\n" | "case \n" | " default: \n" | " return;\n" | "curState = \n" | " switch( cs ) {\n" | "accept = 1; \n" | "break;\n" | "err:\n" | "curState = -1;\n" | ", p );\n" | "ExecFuncs( fsm, f+\n" | "fsm->\n" | "/* Only non-static data: current state. */\n" | "struct \n" | "Struct\n" | " int curState;\n" | " int accept;\n" | "typedef struct \n" | "Struct \n" | "/* Init the fsm. */\n" | "void \n" | "Init( \n" | " *fsm );\n" | "/* Execute some chunk of data. */\n" | "void \n" | "Execute( \n" | " *fsm, char *data, int dlen );\n" | "/* Indicate to the fsm tha there is no more data. */\n" | "void \n" | "Finish( \n" | " *fsm );\n" | "/* Did the machine accept? */\n" | "int \n" | "Accept( \n" | " *fsm );\n" | "/* The start state. */\n" | "static int \n" | "_startState = \n" | "#define f \n" | "#define alph unsigned char\n" | "/* The array of functions. */\n" | "#if \n" | "static int \n" | "_f[] = {\n" | "#endif\n" | "/****************************************\n" | "Init\n" | "void \n" | " *fsm )\n" | " fsm->curState = \n" | "_startState;\n" | " fsm->accept = 0;\n" | "/***************************************************************************\n" | " * Function exection. We do not inline this as in tab\n" | " * code gen because if we did, we might as well just expand \n" | " * the function as in the faster goto code generator.\n" | "static void \n" | "ExecFuncs( \n" | " *fsm, int *funcs, char *p )\n" | " int len = *funcs++;\n" | " while ( len-- > 0 ) {\n" | " switch ( *funcs++ ) {\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | " *fsm, char *data, int dlen )\n" | " /* Prime these to one back to simulate entering the \n" | " * machine on a transition. */ \n" | " register char *p = data - 1;\n" | " register int len = dlen + 1;\n" | " /* Switch statment to enter the machine. */\n" | " switch ( \n" | "curState ) {\n" | "/**********************************************************************\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | " *fsm )\n" | " int cs = fsm->curState;\n" | " int accept = 0;\n" | " fsm->accept = accept;\n" | "/*******************************************************\n" | " * Did the machine accept?\n" | "int \n" | " *fsm )\n" | " return fsm->accept;\n" | "#undef f\n" | "#undef alph\n" | " ExecFuncs( f+\n" | "/* Only non-static data: current state. */\n" | "class \n" | "public:\n" | " /* Init the fsm. */\n" | " void Init( );\n" | " /* Execute some chunk of data. */\n" | " void Execute( char *data, int dlen );\n" | " /* Indicate to the fsm tha there is no more data. */\n" | " void Finish( );\n" | " /* Did the machine accept? */\n" | " int Accept( );\n" | " int curState;\n" | " int accept;\n" | " /* The start state. */\n" | " static int startState;\n" | " /* Function exection. We do not inline this as in tab code gen\n" | " * because if we did, we might as well just expand the function \n" | " * as in the faster goto code generator. */\n" | " void ExecFuncs( int *funcs, char * );\n" | "/* The start state. */\n" | "int \n" | "::startState = \n" | "/* some defines to lessen the code size. */\n" | "#define f \n" | "#endif\n" | "/****************************************\n" | " * Make sure the fsm is initted.\n" | " Init();\n" | "/****************************************\n" | " * Initialize the fsm.\n" | "void \n" | "::Init( )\n" | " curState = startState;\n" | " accept = 0;\n" | "/***************************************************************************\n" | " * Execute functions pointed to by funcs until the null function is found. \n" | "void \n" | "::ExecFuncs( int *funcs, char *p )\n" | " int len = *funcs++;\n" | " while ( len-- > 0 ) {\n" | " switch ( *funcs++ ) {\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | "::Execute( char *data, int dlen )\n" | " /* Prime these to one back to simulate entering the \n" | " * machine on a transition. */ \n" | " register char *p = data - 1;\n" | " register int len = dlen + 1;\n" | " /* Switch statment to enter the machine. */\n" | " switch ( curState ) {\n" | "/**********************************************************************\n" | "::Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | "::Finish( )\n" | " int cs = curState;\n" | " int accept = 0;\n" | " this->accept = accept;\n" | "/*******************************************************\n" | "::Accept\n" | " * Did the machine accept?\n" | "int \n" | "::Accept( )\n" | " return accept;\n" | "#undef f\n" | "#undef alph\n" | "11GotoCodeGen\n" | "12CGotoCodeGen\n" | "13CCGotoCodeGen\n" | "10FsmCodeGen\n" | "bad_alloc\n" | " case \n" | " break;\n" | ", p );\n" | "ExecFuncs( fsm, \n" | "fsm->\n" | "/* Only non-static data: current state. */\n" | "struct \n" | "Struct\n" | " int curState;\n" | " int accept;\n" | "typedef struct \n" | "Struct \n" | "/* Init the fsm. */\n" | "void \n" | "Init( \n" | " *fsm );\n" | "/* Execute some chunk of data. */\n" | "void \n" | "Execute( \n" | " *fsm, char *data, int dlen );\n" | "/* Indicate to the fsm tha there is no more data. */\n" | "void \n" | "Finish( \n" | " *fsm );\n" | "/* Did the machine accept? */\n" | "int \n" | "Accept( \n" | " *fsm );\n" | "/* The start state. */\n" | "static int \n" | "_startState = \n" | "/****************************************\n" | "Init\n" | "void \n" | " *fsm )\n" | " fsm->curState = \n" | "_startState;\n" | " fsm->accept = 0;\n" | "/***************************************************************************\n" | " * Function exection. We do not inline this as in tab\n" | " * code gen because if we did, we might as well just expand \n" | " * the function as in the faster goto code generator.\n" | "static void \n" | "ExecFuncs( \n" | " *fsm, int func, char *p )\n" | " switch ( func ) {\n" | "#define alph unsigned char\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | " *fsm, char *data, int dlen )\n" | " /* Prime these to one back to simulate entering the \n" | " * machine on a transition. */ \n" | " register char *p = data-1;\n" | " register int len = dlen+1;\n" | " /* Switch statment to enter the machine. */\n" | " switch ( \n" | "curState ) {\n" | "/**********************************************************************\n" | "Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | " *fsm )\n" | " int cs = fsm->curState;\n" | " int accept = 0;\n" | " fsm->accept = accept;\n" | "/*******************************************************\n" | "Accept\n" | " * Did the machine accept?\n" | "int \n" | " *fsm )\n" | " return fsm->accept;\n" | "#undef alph\n" | " ExecFuncs( \n" | "/* Only non-static data: current state. */\n" | "class \n" | "public:\n" | " /* Init the fsm. */\n" | " void Init( );\n" | " /* Execute some chunk of data. */\n" | " void Execute( char *data, int dlen );\n" | " /* Indicate to the fsm tha there is no more data. */\n" | " void Finish( );\n" | " /* Did the machine accept? */\n" | " int Accept( );\n" | " int curState;\n" | " int accept;\n" | " /* The start state. */\n" | " static int startState;\n" | " /* Function exection. We do not inline this as in tab code gen\n" | " * because if we did, we might as well just expand the function \n" | " * as in the faster goto code generator. */\n" | " void ExecFuncs( int func, char *p );\n" | "/* The start state. */\n" | "int \n" | "::startState = \n" | " Init();\n" | "/****************************************\n" | "::Init\n" | "void \n" | "::Init( )\n" | " curState = startState;\n" | " accept = 0;\n" | "/***************************************************************************\n" | " * Execute functions pointed to by funcs until the null function is found. \n" | "void \n" | "::ExecFuncs( int func, char *p )\n" | " switch ( func ) {\n" | "::Execute( char *data, int dlen )\n" | " /* Prime these to one back to simulate entering the \n" | " * machine on a transition. */ \n" | " register char *p = data-1;\n" | " register int len = dlen+1;\n" | " /* Switch statment to enter the machine. */\n" | " switch ( curState ) {\n" | "::Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | "::Finish( )\n" | " int cs = curState;\n" | " int accept = 0;\n" | " this->accept = accept;\n" | "/*******************************************************\n" | "::Accept\n" | " * Did the machine accept?\n" | "int \n" | "::Accept( )\n" | " return accept;\n" | "#undef alph\n" | "12FGotoCodeGen\n" | "13CFGotoCodeGen\n" | "14CCFGotoCodeGen\n" | "11GotoCodeGen\n" | "10FsmCodeGen\n" | "bad_alloc\n" | "fsm->\n" | "/* Only non-static data: current state. */\n" | "struct \n" | "Struct\n" | " int curState;\n" | " int accept;\n" | "typedef struct \n" | "Struct \n" | "/* Init the fsm. */\n" | "void \n" | "Init( \n" | " *fsm );\n" | "/* Execute some chunk of data. */\n" | "void \n" | "Execute( \n" | " *fsm, char *data, int dlen );\n" | "/* Indicate to the fsm tha there is no more data. */\n" | "void \n" | "Finish( \n" | " *fsm );\n" | "/* Did the machine accept? */\n" | "int \n" | "Accept( \n" | " *fsm );\n" | "/* The start state. */\n" | "static int \n" | "_startState = \n" | "/****************************************\n" | "Init\n" | "void \n" | " *fsm )\n" | " fsm->curState = \n" | "_startState;\n" | " fsm->accept = 0;\n" | "#define alph unsigned char\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | " *fsm, char *data, int dlen )\n" | " /* Prime these to one back to simulate entering the \n" | " * machine on a transition. */ \n" | " register char *p = data-1;\n" | " register int len = dlen+1;\n" | " /* Switch statment to enter the machine. */\n" | " switch ( \n" | "curState ) {\n" | "/**********************************************************************\n" | "Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | " *fsm )\n" | " int cs = fsm->curState;\n" | " int accept = 0;\n" | " fsm->accept = accept;\n" | "/*******************************************************\n" | "Accept\n" | " * Did the machine accept?\n" | "int \n" | " *fsm )\n" | " return fsm->accept;\n" | "#undef alph\n" | "/* Only non-static data: current state. */\n" | "class \n" | "public:\n" | " /* Init the fsm. */\n" | " void Init( );\n" | " /* Execute some chunk of data. */\n" | " void Execute( char *data, int dlen );\n" | " /* Indicate to the fsm tha there is no more data. */\n" | " void Finish( );\n" | " /* Did the machine accept? */\n" | " int Accept( );\n" | " int curState;\n" | " int accept;\n" | " /* The start state. */\n" | " static int startState;\n" | "/* The start state. */\n" | "int \n" | "::startState = \n" | " Init();\n" | "/****************************************\n" | "::Init\n" | "void \n" | "::Init( )\n" | " curState = startState;\n" | " accept = 0;\n" | "#define alph unsigned char\n" | "/**********************************************************************\n" | " * Execute the fsm on some chunk of data. \n" | "void \n" | "::Execute( char *data, int dlen )\n" | " /* Prime these to one back to simulate entering the \n" | " * machine on a transition. */ \n" | " register char *p = data-1;\n" | " register int len = dlen+1;\n" | " /* Switch statment to enter the machine. */\n" | " switch ( curState ) {\n" | "::Finish\n" | " * Indicate to the fsm that the input is done. Does cleanup tasks.\n" | "void \n" | "::Finish( )\n" | " int cs = curState;\n" | " int accept = 0;\n" | " this->accept = accept;\n" | "/*******************************************************\n" | "::Accept\n" | " * Did the machine accept?\n" | "int \n" | "::Accept( )\n" | " return accept;\n" | "#undef alph\n" | "13IpGotoCodeGen\n" | "14CIpGotoCodeGen\n" | "15CCIpGotoCodeGen\n" | "11GotoCodeGen\n" | "10FsmCodeGen\n"; }%% %% write data; struct strs the_fsm; void test( char *buf ) { struct strs *fsm = &the_fsm; char *p = buf; char *pe = buf + strlen( buf ); %% write init; %% write exec; if ( fsm->cs >= strs_first_final ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "stdin\n" ); test( "bad_alloc\n" ); test( "_GLOBAL_OFFSET_TABLE_\n" ); test( "not in\n" ); test( "isatty\n" "junk on end.\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT ACCEPT FAIL FAIL #endif ragel-6.10/test/repetition.rl0000664000175000017500000000431613065111230013151 00000000000000/* * @LANG: c++ */ /* Test repeptition operators. */ #include #include #include #include using namespace std; struct Rep { int cs; int init( ); int execute( const char *data, int len ); int finish( ); }; %%{ machine Rep; action begin { cout << "begin" << endl; } action in { cout << "in" << endl; } action end { cout << "end" << endl; } a = 'a' >begin @in %end; b = 'b' >begin @in %end; c = 'c' >begin @in %end; d = 'd' >begin @in %end; main := ( a {5} '\n' )* '-\n' ( b {,5} '\n' )* '-\n' ( c {5,} '\n' )* '-\n' ( d {2,5} '\n' )*; }%% %% write data; int Rep::init( ) { %% write init; return 1; } int Rep::execute( const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; if ( cs == Rep_error ) return -1; if ( cs >= Rep_first_final ) return 1; return 0; } int Rep::finish( ) { if ( cs == Rep_error ) return -1; if ( cs >= Rep_first_final ) return 1; return 0; } void test( const char *buf ) { Rep rep; int len = strlen( buf ); rep.init(); rep.execute( buf, len ); if ( rep.finish() > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "aaaaa\n" "-\n" "\n" "b\n" "bb\n" "bbb\n" "bbbb\n" "bbbbb\n" "-\n" "ccccc\n" "ccccccc\n" "cccccccccc\n" "-\n" "dd\n" "ddd\n" "dddd\n" "ddddd\n" ); test( "a\n" "-\n" "b\n" "-\n" "c\n" "-\n" "d\n" ); return 0; } #ifdef _____OUTPUT_____ begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end begin in end ACCEPT begin in FAIL #endif ragel-6.10/test/erract8.rl0000664000175000017500000000127413065111230012337 00000000000000/* * @LANG: java */ class erract8 { %%{ machine erract8; action on_char { System.out.println("char: " + data[p]); } action on_err { System.out.println("err: " + data[p]); } action to_state { System.out.println("to state: " + data[p]); } main := 'heXXX' $on_char $err(on_err) $to(to_state); }%% %% write data; static void test( char data[] ) { int cs, p = 0, pe = data.length; int eof = pe; int top; %% write init; %% write exec; System.out.println("rest: " + data[p] + data[p+1] + data[p+2]); } public static void main( String args[] ) { test( "hello".toCharArray() ); } } /* _____OUTPUT_____ char: h to state: h char: e to state: e err: l rest: llo */ ragel-6.10/test/strings2.h0000664000175000017500000000011313065111230012343 00000000000000#ifndef _STRINGS1_H #define _STRINGS1_H struct strs { int cs; }; #endif ragel-6.10/test/langtrans_csharp.txl0000664000175000017500000001744313065111230014517 00000000000000include "testcase.txl" keys 'bool 'new end keys define csharp_statements [repeat csharp_lang_stmt] end define define csharp_lang_stmt [al_ragel_stmt] | [csharp_variable_decl] | [csharp_expr_stmt] | [csharp_if_stmt] | [EX] '{ [IN] [NL] [csharp_statements] [EX] '} [IN] [NL] end define define csharp_variable_decl [csharp_type_decl] [opt union] [id] '; [NL] end define define csharp_type_decl [al_type_decl] | 'bool | 'String end define define csharp_expr_stmt [csharp_expr] '; [NL] end define define csharp_expr [csharp_term] [repeat csharp_expr_extend] end define define csharp_expr_extend [al_expr_op] [csharp_term] end define define csharp_term [al_term] | [id] [repeat csharp_dot_id] | [id] [repeat csharp_dot_id] '( [csharp_args] ') | 'new [csharp_type_decl] [union] | 'new [csharp_type_decl] '( [csharp_args] ') end define define csharp_dot_id '. [id] end define define csharp_args [list csharp_expr] end define define csharp_sign '- | '+ end define define csharp_if_stmt 'if '( [csharp_expr] ') [NL] [IN] [csharp_lang_stmt] [EX] [opt csharp_else] end define define csharp_else 'else [NL] [IN] [csharp_lang_stmt] [EX] end define define csharp_lang [csharp_statements] '%% [NL] [csharp_statements] [ragel_def] end define define program [lang_indep] | [csharp_lang] end define redefine al_host_block '{ [NL] [IN] [al_statements] [EX] '} [NL] | '{ [NL] [IN] [csharp_statements] [EX] '} [NL] end define redefine cond_action_stmt 'action [id] '{ [al_expr] '} [NL] | 'action [id] '{ [csharp_expr] '} [NL] end redefine function clearUnion Type [csharp_type_decl] Id [id] replace [opt union] Union [union] import ArrayInits [csharp_statements] Stmts [repeat csharp_lang_stmt] export ArrayInits Id '= 'new Type Union '; Stmts by '[] end function rule ptrTypes replace [al_type_decl] 'ptr by 'int end rule function alStmtToCSharp1 AlStmt [action_lang_stmt] deconstruct AlStmt VarDecl [al_variable_decl] deconstruct VarDecl Type [al_type_decl] Id [id] OptUnion [opt union] '; construct CSharpType [csharp_type_decl] Type construct Result [csharp_variable_decl] CSharpType [ptrTypes] OptUnion [clearUnion CSharpType Id] Id '; replace [repeat csharp_lang_stmt] by Result end function rule alTermToCSharp1 replace [al_term] 'first_token_char by 'data '[ts] end rule rule alTermToCSharp2 replace [al_term] '< _ [al_type_decl] '> '( AlExpr [al_expr] ') by '( AlExpr ') end rule function alTermToCSharp replace [al_term] AlTerm [al_term] by AlTerm [alTermToCSharp1] [alTermToCSharp2] end function function alExprExtendToCSharp AlExprExtend [repeat al_expr_extend] deconstruct AlExprExtend Op [al_expr_op] Term [al_term] Rest [repeat al_expr_extend] construct CSharpRest [repeat csharp_expr_extend] _ [alExprExtendToCSharp Rest] replace [repeat csharp_expr_extend] by Op Term [alTermToCSharp] CSharpRest end function function alExprToCSharp AlExpr [al_expr] deconstruct AlExpr ALTerm [al_term] AlExprExtend [repeat al_expr_extend] construct CSharpExprExtend [repeat csharp_expr_extend] _ [alExprExtendToCSharp AlExprExtend] construct Result [opt csharp_expr] ALTerm [alTermToCSharp] CSharpExprExtend replace [opt csharp_expr] by Result end function function alStmtToCSharp2 AlStmt [action_lang_stmt] deconstruct AlStmt AlExpr [al_expr] '; construct OptCSharpExpr [opt csharp_expr] _ [alExprToCSharp AlExpr] deconstruct OptCSharpExpr CSharpExpr [csharp_expr] replace [repeat csharp_lang_stmt] by CSharpExpr '; end function function alOptElseCSharp AlOptElse [opt al_else] deconstruct AlOptElse 'else AlSubStmt [action_lang_stmt] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct CSharpSubStmts [repeat csharp_lang_stmt] _ [alToCSharp AlSubStmts] deconstruct CSharpSubStmts CSharpSubStmt [csharp_lang_stmt] replace [opt csharp_else] by 'else CSharpSubStmt end function function alStmtToCSharp3 AlStmt [action_lang_stmt] deconstruct AlStmt 'if '( AlExpr [al_expr] ') AlSubStmt [action_lang_stmt] AlOptElse [opt al_else] construct OptCSharpExpr [opt csharp_expr] _ [alExprToCSharp AlExpr] deconstruct OptCSharpExpr CSharpExpr [csharp_expr] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct CSharpSubStmts [repeat csharp_lang_stmt] _ [alToCSharp AlSubStmts] deconstruct CSharpSubStmts CSharpSubStmt [csharp_lang_stmt] construct OptCSharpElse [opt csharp_else] _ [alOptElseCSharp AlOptElse] replace [repeat csharp_lang_stmt] by 'if '( CSharpExpr ') CSharpSubStmt OptCSharpElse end function function alStmtToCSharp4a AlStmt [action_lang_stmt] deconstruct AlStmt 'printi Id [id] '; replace [repeat csharp_lang_stmt] by 'Console '. 'Write '( Id '); end function function alStmtToCSharp4b AlStmt [action_lang_stmt] deconstruct AlStmt 'prints String [stringlit] '; replace [repeat csharp_lang_stmt] by 'Console '. 'Write '( String '); end function function alStmtToCSharp4c AlStmt [action_lang_stmt] deconstruct AlStmt 'printb Id [id] '; replace [repeat csharp_lang_stmt] by '_s '= 'new 'String '( Id ', '0 ', 'pos ') '; 'Console '. 'Write '( '_s '); end function function alStmtToCSharp4d AlStmt [action_lang_stmt] deconstruct AlStmt 'print_token '; replace [repeat csharp_lang_stmt] by '_s '= 'new 'String '( 'data ', 'ts ', 'te '- 'ts ') '; 'Console '. 'Write '( '_s '); end function function alStmtToCSharp5 AlStmt [action_lang_stmt] deconstruct AlStmt '{ AlSubStmts [repeat action_lang_stmt] '} construct CSharpSubStmts [repeat csharp_lang_stmt] _ [alToCSharp AlSubStmts] replace [repeat csharp_lang_stmt] by '{ CSharpSubStmts '} end function function alStmtToCSharp6 AlStmt [action_lang_stmt] deconstruct AlStmt RagelStmt [al_ragel_stmt] replace [repeat csharp_lang_stmt] by RagelStmt end function function alToCSharp AlStmts [repeat action_lang_stmt] deconstruct AlStmts FirstStmt [action_lang_stmt] Rest [repeat action_lang_stmt] construct CSharpFirst [repeat csharp_lang_stmt] _ [alStmtToCSharp1 FirstStmt] [alStmtToCSharp2 FirstStmt] [alStmtToCSharp3 FirstStmt] [alStmtToCSharp4a FirstStmt] [alStmtToCSharp4b FirstStmt] [alStmtToCSharp4c FirstStmt] [alStmtToCSharp4d FirstStmt] [alStmtToCSharp5 FirstStmt] [alStmtToCSharp6 FirstStmt] construct CSharpRest [repeat csharp_lang_stmt] _ [alToCSharp Rest] replace [repeat csharp_lang_stmt] by CSharpFirst [. CSharpRest] end function rule actionTransCSharp replace [al_host_block] '{ AlStmts [repeat action_lang_stmt] '} construct CSharpStmts [repeat csharp_lang_stmt] _ [alToCSharp AlStmts] by '{ CSharpStmts '} end rule rule condTransCSharp replace [cond_action_stmt] 'action Id [id] '{ AlExpr [al_expr] '} construct OptCSharpExpr [opt csharp_expr] _ [alExprToCSharp AlExpr] deconstruct OptCSharpExpr CSharpExpr [csharp_expr] by 'action Id '{ CSharpExpr '} end rule rule machineName replace $ [machine_stmt] 'machine _ [id] '; import TXLargs [repeat stringlit] Arg1 [stringlit] _ [repeat stringlit] construct ClassName [id] _ [unquote Arg1] by 'machine ClassName '; end rule function langTransCSharp replace [program] Definitions [repeat action_lang_stmt] '%% Initializations [repeat action_lang_stmt] RagelDef [ragel_def] construct CSharpDefinitions [repeat csharp_lang_stmt] _ [alToCSharp Definitions] construct CSharpInitializations [repeat csharp_lang_stmt] _ [alToCSharp Initializations] construct NewRagelDef [ragel_def] RagelDef [actionTransCSharp] [condTransCSharp] [machineName] import ArrayInits [csharp_statements] ArrayInitStmts [repeat csharp_lang_stmt] by CSharpDefinitions '%% ArrayInitStmts [. CSharpInitializations] NewRagelDef end function function main replace [program] P [program] export ArrayInits [csharp_statements] _ by P [langTransCSharp] end function ragel-6.10/test/runtests.in0000775000175000017500000002037613065111230012656 00000000000000#!/bin/bash # # Copyright 2006-2009 Adrian Thurston # # This file is part of Ragel. # # Ragel is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Ragel is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ragel; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA while getopts "gcnmleT:F:G:P:CDJRAZ" opt; do case $opt in T|F|G|P) genflags="$genflags -$opt$OPTARG" options="$options -$opt$OPTARG" ;; n|m|l|e) minflags="$minflags -$opt" options="$options -$opt" ;; c) compile_only="true" options="$options -$opt" ;; g) allow_generated="true" ;; C|D|J|R|A|Z) langflags="$langflags -$opt" ;; esac done [ -z "$minflags" ] && minflags="-n -m -l -e" [ -z "$genflags" ] && genflags="-T0 -T1 -F0 -F1 -G0 -G1 -G2" [ -z "$langflags" ] && langflags="-C -D -J -R -A -Z" shift $((OPTIND - 1)); [ -z "$*" ] && set -- *.rl config=../src/config.h ragel=../ragel/ragel cxx_compiler="@CXX@" c_compiler="@CC@" objc_compiler="@GOBJC@" d_compiler="@GDC@" java_compiler="@JAVAC@" txl_engine="@TXL@" ruby_engine="@RUBY@" csharp_compiler="@GMCS@" go_compiler="@GOBIN@" function test_error { exit 1; } # split_objs="" # if test $split_iters != "$gen_opt"; then # n=0; # while test $n -lt $split_iters; do # part_root=${root}_`awk 'BEGIN { # width = 0; # high = '$split_iters' - 1; # while ( high > 0 ) { # width = width + 1; # high = int(high / 10); # } # suffFormat = "%" width "." width "d\n"; # printf( suffFormat, '$n' ); # exit 0; # }'` # part_src=${part_root}.c # part_bin=${part_root}.o # echo "$compiler -c $cflags -o $part_bin $part_src" # if ! $compiler -c $cflags -o $part_bin $part_src; then # test_error; # fi # split_objs="$split_objs $part_bin" # n=$((n+1)) # done # fi function run_test() { echo "$ragel $lang_opt $min_opt $gen_opt -o $code_src $test_case" if ! $ragel $lang_opt $min_opt $gen_opt -o $code_src $test_case; then test_error; fi out_args="" [ $lang != java ] && out_args="-o ${binary}"; [ $lang == csharp ] && out_args="-out:${binary}"; # Ruby doesn't need to be compiled. if [ $lang != ruby ]; then echo "$compiler ${cflags} ${out_args} ${code_src}" if ! $compiler ${cflags} ${out_args} ${code_src}; then test_error; fi fi if [ "$compile_only" != "true" ]; then echo -n "running $root ... "; exec_cmd=./$binary [ $lang = java ] && exec_cmd="java ${root}" [ $lang = ruby ] && exec_cmd="ruby ${code_src}" [ $lang = csharp ] && [ "$csharp_compiler" = gmcs ] && exec_cmd="mono ${exec_cmd}" $exec_cmd 2>&1 > $output; if diff --strip-trailing-cr $expected_out $output > /dev/null; then echo "passed"; else echo "FAILED"; test_error; fi; fi } for test_case; do root=${test_case%.rl}; if ! [ -f "$test_case" ]; then echo "runtests: not a file: $test_case"; >&2 exit 1; fi # Check if we should ignore the test case ignore=`sed '/@IGNORE:/s/^.*: *//p;d' $test_case` if [ "$ignore" = yes ]; then continue; fi # If the generated flag is given make sure that the test case is generated. is_generated=`sed '/@GENERATED:/s/^.*: *//p;d' $test_case` if [ "$is_generated" = yes ] && [ "$allow_generated" != true ]; then continue; fi expected_out=$root.exp; sed '1,/_____OUTPUT_____/d;$d' $test_case > $expected_out lang=`sed '/@LANG:/s/^.*: *//p;d' $test_case` if [ -z "$lang" ]; then echo "$test_case: language unset"; >&2 exit 1; fi case $lang in c++) lang_opt=-C; code_suffix=cpp; compiler=$cxx_compiler; cflags="-pedantic -ansi -Wall -O3" ;; d) lang_opt=-D; code_suffix=d; compiler=$d_compiler; cflags="-Wall -O3" ;; c) lang_opt=-C; code_suffix=c; compiler=$c_compiler; cflags="-pedantic -ansi -Wall -O3" ;; obj-c) lang_opt=-C; code_suffix=m; compiler=$objc_compiler cflags="-Wall -O3 -fno-strict-aliasing -lobjc" ;; java) lang_opt=-J; code_suffix=java; compiler=$java_compiler cflags="" ;; ruby) lang_opt=-R; code_suffix=rb; compiler=$ruby_engine cflags="" ;; csharp) lang_opt="-A"; code_suffix=cs; compiler=$csharp_compiler cflags="" ;; go) lang_opt="-Z" code_suffix=go compiler=$go_compiler cflags="" ;; indep) lang_opt=""; # If we have no txl engine then skip this test. [ -z "$txl_engine" ] && continue for lang in c d java ruby csharp go; do case $lang in c) lf="-C";; d) lf="-D";; java) lf="-J";; ruby) lf="-R";; csharp) lf="-A";; go) lf="-Z";; esac echo "$langflags" | grep -e $lf >/dev/null || continue targ=${root}_$lang.rl echo "./langtrans_$lang.sh $test_case > $targ" if ! ./langtrans_$lang.sh $test_case > $targ; then test_error fi echo "./runtests -g $options $targ" if ! ./runtests -g $options $targ; then test_error fi done continue; ;; *) echo "$test_case: unknown language type $lang" >&2 exit 1; ;; esac # Make sure that we are interested in the host language. echo "$langflags" | grep -e $lang_opt >/dev/null || continue code_src=$root.$code_suffix; binary=$root.bin; output=$root.out; # If we have no compiler for the source program then skip it. [ -z "$compiler" ] && continue additional_cflags=`sed '/@CFLAGS:/s/^.*: *//p;d' $test_case` [ -n "$additional_cflags" ] && cflags="$cflags $additional_cflags" allow_minflags=`sed '/@ALLOW_MINFLAGS:/s/^.*: *//p;d' $test_case` [ -z "$allow_minflags" ] && allow_minflags="-n -m -l -e" case $lang in c|c++|d) # Using genflags, get the allowed gen flags from the test case. If the # test case doesn't specify assume that all gen flags are allowed. allow_genflags=`sed '/@ALLOW_GENFLAGS:/s/^.*: *//p;d' $test_case` [ -z "$allow_genflags" ] && allow_genflags="-T0 -T1 -F0 -F1 -G0 -G1 -G2" for min_opt in $minflags; do echo "$allow_minflags" | grep -e $min_opt >/dev/null || continue for gen_opt in $genflags; do echo "$allow_genflags" | grep -e $gen_opt >/dev/null || continue run_test done done ;; java) # Not interested in gen opt. gen_opt="" for min_opt in $minflags; do echo "$allow_minflags" | grep -e $min_opt >/dev/null || continue run_test done ;; ruby) # Using genflags, get the allowed gen flags from the test case. If the # test case doesn't specify assume that all gen flags are allowed. allow_genflags=`sed '/@ALLOW_GENFLAGS:/s/^.*: *//p;d' $test_case` [ -z "$allow_genflags" ] && allow_genflags="-T0 -T1 -F0 -F1" for min_opt in $minflags; do echo "$allow_minflags" | grep -e $min_opt >/dev/null || continue for gen_opt in $genflags; do echo "$allow_genflags" | grep -e $gen_opt >/dev/null || continue run_test done done ;; csharp) # Using genflags, get the allowed gen flags from the test case. If the # test case doesn't specify assume that all gen flags are allowed. allow_genflags=`sed '/@ALLOW_GENFLAGS:/s/^.*: *//p;d' $test_case` [ -z "$allow_genflags" ] && allow_genflags="-T0 -T1 -F0 -F1 -G0 -G1" for min_opt in $minflags; do echo "$allow_minflags" | grep -e $min_opt >/dev/null || continue for gen_opt in $genflags; do echo "$allow_genflags" | grep -e $gen_opt >/dev/null || continue run_test done done ;; go) # Using genflags, get the allowed gen flags from the test case. If the # test case doesn't specify assume that all gen flags are allowed. allow_genflags=`sed '/@ALLOW_GENFLAGS:/s/^.*: *//p;d' $test_case` [ -z "$allow_genflags" ] && allow_genflags="-T0 -T1 -F0 -F1 -G0 -G1 -G2" for min_opt in $minflags; do echo "$allow_minflags" | grep -e $min_opt >/dev/null || continue for gen_opt in $genflags; do echo "$allow_genflags" | grep -e $gen_opt >/dev/null || continue run_test done done ;; esac done ragel-6.10/test/export4.rl0000664000175000017500000000142213065111230012367 00000000000000/* * @LANG: d */ import std.c.stdio; import std.string; %%{ machine test; export c1 = 'c'; export c2 = 'z'; export c3 = 't'; commands := ( c1 . digit* '\n' @{ printf( "c1\n" );} | c2 . alpha* '\n' @{ printf( "c2\n" );}| c3 . '.'* '\n' @{ printf( "c3\n" );} )*; some_other := any*; }%% %% write exports; %% write data; int test( char data[] ) { int cs = test_en_commands; char *p = data.ptr, pe = data.ptr + data.length; %% write init nocs; %% write exec; if ( cs >= test_first_final ) printf("ACCEPT\n"); else printf("ERROR\n"); return 0; } char data[] = [ test_ex_c1, '1', '2', '\n', test_ex_c2, 'a', 'b', '\n', test_ex_c3, '.', '.', '\n' ]; int main() { test( data ); return 0; } /+ _____OUTPUT_____ c1 c2 c3 ACCEPT ++++++++++++++++++/ ragel-6.10/test/langtrans_c.sh0000775000175000017500000000352413065111230013262 00000000000000#!/bin/bash # file=$1 [ -f $file ] || exit 1 # Get the machine name. machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' $file` # Make a temporary version of the test case using the C language translations. sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_c.txl > $file.pr needs_eof=`sed '/@NEEDS_EOF/s/^.*$/yes/p;d' $file` if [ "$needs_eof" != 'yes' ]; then needs_eof=`sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin checkeofact.txl` fi # Begin writing out the test case. cat << EOF /* * @LANG: c * @GENERATED: yes EOF grep '@ALLOW_GENFLAGS:' $file grep '@ALLOW_MINFLAGS:' $file cat << EOF */ #include #include EOF # Write the data declarations sed -n '/^%%$/q;p' $file.pr # Write out the machine specification. sed -n '/^%%{$/,/^}%%/p' $file.pr # Write out the init and execute routines. cat << EOF int cs; %% write data; void init() { EOF sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t/;p}' $file.pr cat << EOF %% write init; } void exec( char *data, int len ) { char *p = data; char *pe = data + len; EOF [ "$needs_eof" = "yes" ] && echo "char *eof = pe;" cat << EOF %% write exec; } void finish( ) { if ( cs >= ${machine}_first_final ) printf( "ACCEPT\\n" ); else printf( "FAIL\\n" ); } EOF # Write out the test data. sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' BEGIN { print "char *inp[] = {" } { print " " $0 "," } END { print "};" print "" print "int inplen = " NR ";" }' # Write out the main routine. cat << EOF int main( ) { int i; for ( i = 0; i < inplen; i++ ) { init(); exec( inp[i], strlen(inp[i]) ); finish(); } return 0; } #ifdef _____OUTPUT_____ EOF # Write out the expected output. sed -n '0,/\/\* _____OUTPUT_____/d; /_____OUTPUT_____ \*\//q; p;' $file echo "#endif" # Don't need this language-specific file anymore. rm $file.pr ragel-6.10/test/atoi1.rl0000664000175000017500000000126313065111230012002 00000000000000/* * @LANG: indep */ bool neg; int val; %% val = 0; neg = false; %%{ machine AtoI; action begin { neg = false; val = 0; } action see_neg { neg = true; } action add_digit { val = val * 10 + (fc - 48); } action finish { if ( neg ) { val = -1 * val; } } action print { printi val; prints "\n"; } atoi = ( ('-'@see_neg | '+')? (digit @add_digit)+ ) >begin %finish; main := atoi '\n' @print; }%% /* _____INPUT_____ "1\n" "12\n" "222222\n" "+2123\n" "213 3213\n" "-12321\n" "--123\n" "-99\n" " -3000\n" _____INPUT_____ */ /* _____OUTPUT_____ 1 ACCEPT 12 ACCEPT 222222 ACCEPT 2123 ACCEPT FAIL -12321 ACCEPT FAIL -99 ACCEPT FAIL _____OUTPUT_____ */ ragel-6.10/test/erract5.rl0000664000175000017500000000454413065111230012337 00000000000000/* * @LANG: obj-c */ /* * Test error actions. */ #include #include #include @interface ErrAct : Object { @public 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. - (int) initFsm; // 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) executeWithData:(const char *)data len:(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; @end @implementation ErrAct %%{ machine ErrAct; action expect_digit_plus_minus { printf(" DIGIT PLUS MINUS\n"); } action expect_digit { printf(" DIGIT\n"); } action expect_digit_decimal { printf(" DIGIT DECIMAL\n"); } float = ( ( [\-+] >!expect_digit_plus_minus %!expect_digit | "" ) ( [0-9] [0-9]* $!expect_digit_decimal ) ( '.' [0-9]+ $!expect_digit )? ); main := float '\n'; }%% %% write data; - (int) initFsm; { %% write init; return 1; } - (void) executeWithData:(const char *)_data len:(int)_len; { const char *p = _data; const char *pe = _data + _len; const char *eof = pe; %% write exec; } - (int) finish; { if ( cs == ErrAct_error ) return -1; else if ( cs >= ErrAct_first_final ) return 1; return 0; } @end #define BUFSIZE 1024 void test( char *buf ) { ErrAct *errAct = [[ErrAct alloc] init]; [errAct initFsm]; [errAct executeWithData:buf len:strlen(buf)]; if ( [errAct finish] > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "1\n" ); test( "+1\n" ); test( "-1\n" ); test( "1.1\n" ); test( "+1.1\n" ); test( "-1.1\n" ); test( "a\n" ); test( "-\n" ); test( "+\n" ); test( "-a\n" ); test( "+b\n" ); test( "1.\n" ); test( "1d\n" ); test( "1.d\n" ); test( "1.1d\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT ACCEPT ACCEPT ACCEPT ACCEPT DIGIT PLUS MINUS FAIL DIGIT FAIL DIGIT FAIL DIGIT FAIL DIGIT FAIL DIGIT FAIL DIGIT DECIMAL FAIL DIGIT FAIL DIGIT FAIL #endif ragel-6.10/test/high3.rl0000664000175000017500000000362613065111230011774 00000000000000/* * @LANG: obj-c */ /** * Test a high character to make sure signedness * isn't messing us up. */ #include #include @interface Fsm : Object { @public 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. - (int) initFsm; // 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) executeWithData:(const unsigned char *)data len:(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; @end @implementation Fsm %%{ machine Fsm; alphtype unsigned char; # Indicate we got the high character. action gothigh { printf("yes\n"); } main := 0xe8 @gothigh '\n'; }%% %% write data; - (int) initFsm; { %% write init; return 1; } - (void) executeWithData:(const unsigned char *)_data len:(int)_len; { const unsigned char *p = _data; const unsigned char *pe = _data + _len; %% write exec; } - (int) finish; { if ( cs == Fsm_error ) return -1; else if ( cs >= Fsm_first_final ) return 1; return 0; } @end #define BUFSIZE 2048 Fsm *fsm; unsigned char buf[BUFSIZE]; void test( unsigned char *buf, int len ) { fsm = [[Fsm alloc] init]; [fsm initFsm]; [fsm executeWithData:buf len:len]; if ( [fsm finish] > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } unsigned char data1[] = { 0xe8, 10 }; unsigned char data2[] = { 0xf8, 10 }; int main() { test( data1, 2 ); test( data2, 2 ); return 0; } #ifdef _____OUTPUT_____ yes ACCEPT FAIL #endif ragel-6.10/test/atoi3.rl0000664000175000017500000000163013065111230012002 00000000000000# # @LANG: ruby # %%{ machine atoi3; action begin { neg = false; val = 0; } action see_neg { neg = true; } action add_digit { val = val * 10 + (fc - "0"[0]); } action finish { val = -1 * val if neg } action print { puts val; } atoi = (('-' @ see_neg | '+') ? (digit @ add_digit) +) > begin % finish; main := atoi '\n' @ print; }%% %% write data; def run_machine( data ) p = 0; pe = data.length cs = 0 val = 0; neg = false; %% write init; %% write exec; if cs >= atoi3_first_final puts "ACCEPT" else puts "FAIL" end end inp = [ "1\n", "12\n", "222222\n", "+2123\n", "213 3213\n", "-12321\n", "--123\n", "-99\n", " -3000\n", ] inp.each { |str| run_machine(str) } =begin _____OUTPUT_____ 1 ACCEPT 12 ACCEPT 222222 ACCEPT 2123 ACCEPT FAIL -12321 ACCEPT FAIL -99 ACCEPT FAIL =end _____OUTPUT_____ ragel-6.10/test/clang1.rl0000664000175000017500000001371013065111230012132 00000000000000/* * @LANG: c * A mini C-like language scanner. */ #include #include #define IDENT_BUFLEN 256 %%{ machine clang; # Function to buffer a character. action bufChar { if ( identLen < IDENT_BUFLEN ) { identBuf[identLen] = fc; identLen += 1; } } # Function to clear the buffer. action clearBuf { identLen = 0; } # Functions to dump tokens as they are matched. action ident { identBuf[identLen] = 0; printf("ident(%i): %s\n", curLine, identBuf); } action literal { identBuf[identLen] = 0; printf("literal(%i): %s\n", curLine, identBuf); } action float { identBuf[identLen] = 0; printf("float(%i): %s\n", curLine, identBuf); } action int { identBuf[identLen] = 0; printf("int(%i): %s\n", curLine, identBuf); } action hex { identBuf[identLen] = 0; printf("hex(%i): 0x%s\n", curLine, identBuf); } action symbol { identBuf[identLen] = 0; printf("symbol(%i): %s\n", curLine, identBuf); } # Alpha numberic characters or underscore. alnumu = alnum | '_'; # Alpha charactres or underscore. alphau = alpha | '_'; # Symbols. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving dump the symbol. symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; # Identifier. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving, dump the identifier. ident = (alphau . alnumu*) >clearBuf $bufChar %ident; # Match single characters inside literal strings. Or match # an escape sequence. Buffers the charater matched. sliteralChar = ( extend - ['\\] ) @bufChar | ( '\\' . extend @bufChar ); dliteralChar = ( extend - ["\\] ) @bufChar | ( '\\' . extend @bufChar ); # Single quote and double quota literals. At the start clear # the buffer. Upon leaving dump the literal. sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; literal = sliteral | dliteral; # Whitespace is standard ws, newlines and control codes. whitespace = any - 0x21..0x7e; # Describe both c style comments and c++ style comments. The # priority bump on tne terminator of the comments brings us # out of the extend* which matches everything. ccComment = '//' . extend* $0 . '\n' @1; cComment = '/*' . extend* $0 . '*/' @1; # Match an integer. We don't bother clearing the buf or filling it. # The float machine overlaps with int and it will do it. int = digit+ %int; # Match a float. Upon entering the machine clear the buf, buffer # characters on every trans and dump the float upon leaving. float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; # Match a hex. Upon entering the hex part, clear the buf, buffer characters # on every trans and dump the hex on leaving transitions. hex = '0x' . xdigit+ >clearBuf $bufChar %hex; # Or together all the lanuage elements. fin = ( ccComment | cComment | symbol | ident | literal | whitespace | int | float | hex ); # Star the language elements. It is critical in this type of application # that we decrease the priority of out transitions before doing so. This # is so that when we see 'aa' we stay in the fin machine to match an ident # of length two and not wrap around to the front to match two idents of # length one. clang_main = ( fin $1 %0 )*; # This machine matches everything, taking note of newlines. newline = ( any | '\n' @{ curLine += 1; } )*; # The final fsm is the lexer intersected with the newline machine which # will count lines for us. Since the newline machine accepts everything, # the strings accepted is goverened by the clang_main machine, onto which # the newline machine overlays line counting. main := clang_main & newline; }%% #include %% write data noerror; char data[] = "/*\n" " * Copyright\n" " */\n" "\n" "/* Aapl.\n" " */\n" " \n" "#define _AAPL_RESIZE_H\n" "\n" "#include \n" "\n" "#ifdef AAPL_NAMESPACE\n" "namespace Aapl {\n" "#endif\n" "#define LIN_DEFAULT_STEP 256\n" "#define EXPN_UP( existing, needed ) \\\n" " need > eng ? (ned<<1) : eing\n" " \n" "\n" "/*@}*/\n" "#undef EXPN_UP\n" "#ifdef AAPL_NAMESPACE\n" "#endif /* _AAPL_RESIZE_H */\n"; void test( char *buf ) { int len = strlen( buf ); char *p = buf, *pe = buf + len; char *eof = pe; char identBuf[IDENT_BUFLEN+1]; int identLen; int curLine; int cs; identLen = 0; curLine = 1; %% write init; %% write exec; if ( cs >= clang_first_final ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "999 0xaAFF99 99.99 /*\n" "*/ 'lksdj' //\n" "\"\n" "\n" "literal\n" "\n" "\n" "\"0x00aba foobardd.ddsf 0x0.9\n" ); test( "wordwithnum00asdf\n" "000wordfollowsnum,makes new symbol\n" "\n" "finishing early /* unfinished ...\n" ); test( data ); return 0; } #ifdef _____OUTPUT_____ int(1): 999 hex(1): 0xaAFF99 float(1): 99.99 literal(2): lksdj literal(8): literal hex(8): 0x00aba ident(8): foobardd symbol(8): . ident(8): ddsf hex(8): 0x0 symbol(8): . int(8): 9 ACCEPT ident(1): wordwithnum00asdf int(2): 000 ident(2): wordfollowsnum symbol(2): , ident(2): makes ident(2): new ident(2): symbol ident(4): finishing ident(4): early FAIL symbol(8): # ident(8): define ident(8): _AAPL_RESIZE_H symbol(10): # ident(10): include symbol(10): < ident(10): assert symbol(10): . ident(10): h symbol(10): > symbol(12): # ident(12): ifdef ident(12): AAPL_NAMESPACE ident(13): namespace ident(13): Aapl symbol(13): { symbol(14): # ident(14): endif symbol(15): # ident(15): define ident(15): LIN_DEFAULT_STEP int(15): 256 symbol(16): # ident(16): define ident(16): EXPN_UP symbol(16): ( ident(16): existing symbol(16): , ident(16): needed symbol(16): ) symbol(16): \ ident(17): need symbol(17): > ident(17): eng symbol(17): ? symbol(17): ( ident(17): ned symbol(17): < symbol(17): < int(17): 1 symbol(17): ) symbol(17): : ident(17): eing symbol(21): # ident(21): undef ident(21): EXPN_UP symbol(22): # ident(22): ifdef ident(22): AAPL_NAMESPACE symbol(23): # ident(23): endif ACCEPT #endif ragel-6.10/test/java1.rl0000664000175000017500000000132213065111230011763 00000000000000/* * @LANG: java */ class java1 { %%{ machine java1; one := 'one\n'; two := 'two\n'; four := 'four\n'; main := ( 'hello' | 'there' | 'friend' ) '\n' @{int s = fentry(one); fgoto *s; char c = fc;} ( 'one' | 'two' | 'four' ) '\n'; }%% %% write data; static void test( char data[] ) { int cs, p = 0, pe = data.length; int top; %% write init; %% write exec; if ( cs >= java1_first_final ) System.out.println( "ACCEPT" ); else System.out.println( "FAIL" ); } public static void main( String args[] ) { test( "hello\none\n".toCharArray() ); test( "there\ntwo\n".toCharArray() ); test( "friend\nfour\n".toCharArray() ); } } /* _____OUTPUT_____ ACCEPT FAIL FAIL */ ragel-6.10/test/forder2.rl0000664000175000017500000000333113065111230012326 00000000000000/* * @LANG: c */ #include #include /* * After the fact start and ending transitions. Behaves like constructors of * and destructors in c++. */ struct forder { int cs; }; %%{ machine forder; variable cs fsm->cs; inner = 'inner' >{printf("enter inner\n");} ${printf("inside inner\n");} %{printf("leave inner\n");} ; outter = inner >{printf("enter outter\n");} ${printf("inside outter\n");} %{printf("leave outter\n");} ; main := outter . '\n'; }%% %% write data; void forder_init( struct forder *fsm ) { %% write init; } void forder_execute( struct forder *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int forder_finish( struct forder *fsm ) { if ( fsm->cs == forder_error ) return -1; if ( fsm->cs >= forder_first_final ) return 1; return 0; } struct forder fsm; void test( char *buf ) { int len = strlen( buf ); forder_init( &fsm ); forder_execute( &fsm, buf, len ); if ( forder_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "inner\n"); test( "inner\n" "foobar\n" ); test( "" ); test( "\n" ); test( "inn\n" ); return 0; } #ifdef _____OUTPUT_____ enter outter enter inner inside inner inside outter inside inner inside outter inside inner inside outter inside inner inside outter inside inner inside outter leave inner leave outter ACCEPT enter outter enter inner inside inner inside outter inside inner inside outter inside inner inside outter inside inner inside outter inside inner inside outter leave inner leave outter FAIL FAIL FAIL enter outter enter inner inside inner inside outter inside inner inside outter inside inner inside outter FAIL #endif ragel-6.10/test/erract7.rl0000664000175000017500000000104513065111230012332 00000000000000/* * @LANG: c */ #include #include %%{ machine foo; action on_char { printf("char: %c\n", *p); } action on_err { printf("err: %c\n", *p); } action to_state { printf("to state: %c\n", *p); } main := 'heXXX' $on_char $err(on_err) $to(to_state); }%% %% write data; int main() { int cs; char *p = "hello", *pe = p + strlen(p); char *eof = pe; %%{ write init; write exec; }%% printf( "rest: %s\n", p ); return 0; } #ifdef _____OUTPUT_____ char: h to state: h char: e to state: e err: l rest: llo #endif ragel-6.10/test/langtrans_java.sh0000775000175000017500000000327413065111230013763 00000000000000#!/bin/bash # file=$1 [ -f $file ] || exit 1 root=${file%.rl} class=${root}_java # Make a temporary version of the test case using the Java language translations. sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_java.txl - $class > $file.pr # Begin writing out the test case. cat << EOF /* * @LANG: java * @GENERATED: yes EOF grep '@ALLOW_GENFLAGS:' $file grep '@ALLOW_MINFLAGS:' $file cat << EOF */ class $class { EOF # Write the data declarations sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr # Write out the machine specification. sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr # Write out the init and execute routines. cat << EOF int cs; %% write data; void init() { EOF sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr cat << EOF %% write init; } void exec( char data[], int len ) { int p = 0; int pe = len; int eof = len; String _s; %% write exec; } void finish( ) { if ( cs >= ${class}_first_final ) System.out.println( "ACCEPT" ); else System.out.println( "FAIL" ); } EOF # Write out the test data. sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' BEGIN { print " static final String inp[] = {" } { print " " $0 "," } END { print " };" print "" print " static final int inplen = " NR ";" }' # Write out the main routine. cat << EOF public static void main (String[] args) { $class machine = new $class(); for ( int i = 0; i < inplen; i++ ) { machine.init(); machine.exec( inp[i].toCharArray(), inp[i].length() ); machine.finish(); } } } EOF # Write out the expected output. sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//p;' $file # Don't need this language-specific file anymore. rm $file.pr ragel-6.10/test/langtrans_java.txl0000664000175000017500000001710713065111230014155 00000000000000include "testcase.txl" keys 'boolean 'new end keys define java_statements [repeat java_lang_stmt] end define define java_lang_stmt [al_ragel_stmt] | [java_variable_decl] | [java_expr_stmt] | [java_if_stmt] | [EX] '{ [IN] [NL] [java_statements] [EX] '} [IN] [NL] end define define java_variable_decl [java_type_decl] [id] [opt union] '; [NL] end define define java_type_decl [al_type_decl] | 'boolean | 'String end define define java_expr_stmt [java_expr] '; [NL] end define define java_expr [java_term] [repeat java_expr_extend] end define define java_expr_extend [al_expr_op] [java_term] end define define java_term [al_term] | [id] [repeat java_dot_id] | [id] [repeat java_dot_id] '( [java_args] ') | 'new [java_type_decl] [union] | 'new [java_type_decl] '( [java_args] ') end define define java_dot_id '. [id] end define define java_args [list java_expr] end define define java_sign '- | '+ end define define java_if_stmt 'if '( [java_expr] ') [NL] [IN] [java_lang_stmt] [EX] [opt java_else] end define define java_else 'else [NL] [IN] [java_lang_stmt] [EX] end define define java_lang [java_statements] '%% [NL] [java_statements] [ragel_def] end define define program [lang_indep] | [java_lang] end define redefine al_host_block '{ [NL] [IN] [al_statements] [EX] '} [NL] | '{ [NL] [IN] [java_statements] [EX] '} [NL] end define redefine cond_action_stmt 'action [id] '{ [al_expr] '} [NL] | 'action [id] '{ [java_expr] '} [NL] end redefine function clearUnion Type [java_type_decl] Id [id] replace [opt union] Union [union] import ArrayInits [java_statements] Stmts [repeat java_lang_stmt] export ArrayInits Id '= 'new Type Union '; Stmts by '[] end function rule boolTypes replace [java_type_decl] 'bool by 'boolean end rule rule ptrTypes replace [al_type_decl] 'ptr by 'int end rule function alStmtToJava1 AlStmt [action_lang_stmt] deconstruct AlStmt VarDecl [al_variable_decl] deconstruct VarDecl Type [al_type_decl] Id [id] OptUnion [opt union] '; construct JavaType [java_type_decl] Type construct Result [java_variable_decl] JavaType [boolTypes] [ptrTypes] Id OptUnion [clearUnion JavaType Id] '; replace [repeat java_lang_stmt] by Result end function rule alTermToJava1 replace [al_term] 'first_token_char by 'data '[ts] end rule rule alTermToJava2 replace [al_term] '< _ [al_type_decl] '> '( AlExpr [al_expr] ') by '( AlExpr ') end rule function alTermToJava replace [al_term] AlTerm [al_term] by AlTerm [alTermToJava1] [alTermToJava2] end function function alExprExtendToJava AlExprExtend [repeat al_expr_extend] deconstruct AlExprExtend Op [al_expr_op] Term [al_term] Rest [repeat al_expr_extend] construct JavaRest [repeat java_expr_extend] _ [alExprExtendToJava Rest] replace [repeat java_expr_extend] by Op Term [alTermToJava] JavaRest end function function alExprToJava AlExpr [al_expr] deconstruct AlExpr ALTerm [al_term] AlExprExtend [repeat al_expr_extend] construct JavaExprExtend [repeat java_expr_extend] _ [alExprExtendToJava AlExprExtend] construct Result [opt java_expr] ALTerm [alTermToJava] JavaExprExtend replace [opt java_expr] by Result end function function alStmtToJava2 AlStmt [action_lang_stmt] deconstruct AlStmt AlExpr [al_expr] '; construct OptJavaExpr [opt java_expr] _ [alExprToJava AlExpr] deconstruct OptJavaExpr JavaExpr [java_expr] replace [repeat java_lang_stmt] by JavaExpr '; end function function alOptElseJava AlOptElse [opt al_else] deconstruct AlOptElse 'else AlSubStmt [action_lang_stmt] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct JavaSubStmts [repeat java_lang_stmt] _ [alToJava AlSubStmts] deconstruct JavaSubStmts JavaSubStmt [java_lang_stmt] replace [opt java_else] by 'else JavaSubStmt end function function alStmtToJava3 AlStmt [action_lang_stmt] deconstruct AlStmt 'if '( AlExpr [al_expr] ') AlSubStmt [action_lang_stmt] AlOptElse [opt al_else] construct OptJavaExpr [opt java_expr] _ [alExprToJava AlExpr] deconstruct OptJavaExpr JavaExpr [java_expr] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct JavaSubStmts [repeat java_lang_stmt] _ [alToJava AlSubStmts] deconstruct JavaSubStmts JavaSubStmt [java_lang_stmt] construct OptJavaElse [opt java_else] _ [alOptElseJava AlOptElse] replace [repeat java_lang_stmt] by 'if '( JavaExpr ') JavaSubStmt OptJavaElse end function function alStmtToJava4a AlStmt [action_lang_stmt] deconstruct AlStmt 'printi Id [id] '; replace [repeat java_lang_stmt] by 'System '. 'out '. 'print '( Id '); end function function alStmtToJava4b AlStmt [action_lang_stmt] deconstruct AlStmt 'prints String [stringlit] '; replace [repeat java_lang_stmt] by 'System '. 'out '. 'print '( String '); end function function alStmtToJava4c AlStmt [action_lang_stmt] deconstruct AlStmt 'printb Id [id] '; replace [repeat java_lang_stmt] by '_s '= 'new 'String '( Id ', '0 ', 'pos ') '; 'System '. 'out '. 'print '( '_s '); end function function alStmtToJava4d AlStmt [action_lang_stmt] deconstruct AlStmt 'print_token '; replace [repeat java_lang_stmt] by '_s '= 'new 'String '( 'data ', 'ts ', 'te '- 'ts ') '; 'System '. 'out '. 'print '( '_s '); end function function alStmtToJava5 AlStmt [action_lang_stmt] deconstruct AlStmt '{ AlSubStmts [repeat action_lang_stmt] '} construct JavaSubStmts [repeat java_lang_stmt] _ [alToJava AlSubStmts] replace [repeat java_lang_stmt] by '{ JavaSubStmts '} end function function alStmtToJava6 AlStmt [action_lang_stmt] deconstruct AlStmt RagelStmt [al_ragel_stmt] replace [repeat java_lang_stmt] by RagelStmt end function function alToJava AlStmts [repeat action_lang_stmt] deconstruct AlStmts FirstStmt [action_lang_stmt] Rest [repeat action_lang_stmt] construct JavaFirst [repeat java_lang_stmt] _ [alStmtToJava1 FirstStmt] [alStmtToJava2 FirstStmt] [alStmtToJava3 FirstStmt] [alStmtToJava4a FirstStmt] [alStmtToJava4b FirstStmt] [alStmtToJava4c FirstStmt] [alStmtToJava4d FirstStmt] [alStmtToJava5 FirstStmt] [alStmtToJava6 FirstStmt] construct JavaRest [repeat java_lang_stmt] _ [alToJava Rest] replace [repeat java_lang_stmt] by JavaFirst [. JavaRest] end function rule actionTransJava replace [al_host_block] '{ AlStmts [repeat action_lang_stmt] '} construct JavaStmts [repeat java_lang_stmt] _ [alToJava AlStmts] by '{ JavaStmts '} end rule rule condTransJava replace [cond_action_stmt] 'action Id [id] '{ AlExpr [al_expr] '} construct OptJavaExpr [opt java_expr] _ [alExprToJava AlExpr] deconstruct OptJavaExpr JavaExpr [java_expr] by 'action Id '{ JavaExpr '} end rule rule machineName replace $ [machine_stmt] 'machine _ [id] '; import TXLargs [repeat stringlit] Arg1 [stringlit] _ [repeat stringlit] construct ClassName [id] _ [unquote Arg1] by 'machine ClassName '; end rule function langTransJava replace [program] Definitions [repeat action_lang_stmt] '%% Initializations [repeat action_lang_stmt] RagelDef [ragel_def] construct JavaDefinitions [repeat java_lang_stmt] _ [alToJava Definitions] construct JavaInitializations [repeat java_lang_stmt] _ [alToJava Initializations] construct NewRagelDef [ragel_def] RagelDef [actionTransJava] [condTransJava] [machineName] import ArrayInits [java_statements] ArrayInitStmts [repeat java_lang_stmt] by JavaDefinitions '%% ArrayInitStmts [. JavaInitializations] NewRagelDef end function function main replace [program] P [program] export ArrayInits [java_statements] _ by P [langTransJava] end function ragel-6.10/test/clang2.rl0000664000175000017500000001502413065111230012133 00000000000000/* * @LANG: obj-c * A mini C-like language scanner. */ #include #include #include #define IDENT_BUFLEN 256 @interface Clang : Object { @public /* State machine operation data. */ int cs; /* Parsing data. */ char identBuf[IDENT_BUFLEN+1]; int identLen; int curLine; }; - (void) initFsm; - (void) executeWithData:(const char *)data len:(int)len; - (int) finish; @end %%{ machine Clang; # Function to buffer a character. action bufChar { if ( identLen < IDENT_BUFLEN ) { identBuf[identLen] = fc; identLen += 1; } } # Function to clear the buffer. action clearBuf { identLen = 0; } # Functions to dump tokens as they are matched. action ident { identBuf[identLen] = 0; printf("ident(%i): %s\n", curLine, identBuf); } action literal { identBuf[identLen] = 0; printf("literal(%i): %s\n", curLine, identBuf); } action float { identBuf[identLen] = 0; printf("float(%i): %s\n", curLine, identBuf); } action int { identBuf[identLen] = 0; printf("int(%i): %s\n", curLine, identBuf); } action hex { identBuf[identLen] = 0; printf("hex(%i): 0x%s\n", curLine, identBuf); } action symbol { identBuf[identLen] = 0; printf("symbol(%i): %s\n", curLine, identBuf); } # Alpha numberic characters or underscore. alnumu = alnum | '_'; # Alpha charactres or underscore. alphau = alpha | '_'; # Symbols. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving dump the symbol. symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; # Identifier. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving, dump the identifier. ident = (alphau . alnumu*) >clearBuf $bufChar %ident; # Match single characters inside literal strings. Or match # an escape sequence. Buffers the charater matched. sliteralChar = ( extend - ['\\] ) @bufChar | ( '\\' . extend @bufChar ); dliteralChar = ( extend - ["\\] ) @bufChar | ( '\\' . extend @bufChar ); # Single quote and double quota literals. At the start clear # the buffer. Upon leaving dump the literal. sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; literal = sliteral | dliteral; # Whitespace is standard ws, newlines and control codes. whitespace = any - 0x21..0x7e; # Describe both c style comments and c++ style comments. The # priority bump on tne terminator of the comments brings us # out of the extend* which matches everything. ccComment = '//' . extend* $0 . '\n' @1; cComment = '/*' . extend* $0 . '*/' @1; # Match an integer. We don't bother clearing the buf or filling it. # The float machine overlaps with int and it will do it. int = digit+ %int; # Match a float. Upon entering the machine clear the buf, buffer # characters on every trans and dump the float upon leaving. float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; # Match a hex. Upon entering the hex part, clear the buf, buffer characters # on every trans and dump the hex on leaving transitions. hex = '0x' . xdigit+ >clearBuf $bufChar %hex; # Or together all the lanuage elements. fin = ( ccComment | cComment | symbol | ident | literal | whitespace | int | float | hex ); # Star the language elements. It is critical in this type of application # that we decrease the priority of out transitions before doing so. This # is so that when we see 'aa' we stay in the fin machine to match an ident # of length two and not wrap around to the front to match two idents of # length one. clang_main = ( fin $1 %0 )*; # This machine matches everything, taking note of newlines. newline = ( any | '\n' @{ curLine += 1; } )*; # The final fsm is the lexer intersected with the newline machine which # will count lines for us. Since the newline machine accepts everything, # the strings accepted is goverened by the clang_main machine, onto which # the newline machine overlays line counting. main := clang_main & newline; }%% @implementation Clang %% write data; - (void) initFsm; { identLen = 0; curLine = 1; %% write init; } - (void) executeWithData:(const char *)data len:(int)len; { const char *p = data; const char *pe = data + len; const char *eof = pe; %% write exec; } - (int) finish; { if ( cs == Clang_error ) return -1; if ( cs >= Clang_first_final ) return 1; return 0; } @end #define BUFSIZE 2048 Clang *fsm; char buf[BUFSIZE]; void test( char *buf ) { int len = strlen(buf); fsm = [[Clang alloc] init]; [fsm initFsm]; [fsm executeWithData:buf len:len]; if ( [fsm finish] > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "999 0xaAFF99 99.99 /*\n" "*/ 'lksdj' //\n" "\"\n" "\n" "literal\n" "\n" "\n" "\"0x00aba foobardd.ddsf 0x0.9\n" ); test( "wordwithnum00asdf\n" "000wordfollowsnum,makes new symbol\n" "\n" "finishing early /* unfinished ...\n" ); test( "/*\n" " * Copyright\n" " */\n" "\n" "/* Aapl.\n" " */\n" " \n" "#define _AAPL_RESIZE_H\n" "\n" "#include \n" "\n" "#ifdef AAPL_NAMESPACE\n" "namespace Aapl {\n" "#endif\n" "#define LIN_DEFAULT_STEP 256\n" "#define EXPN_UP( existing, needed ) \\\n" " need > eng ? (ned<<1) : eing\n" " \n" "\n" "/*@}*/\n" "#undef EXPN_UP\n" "#ifdef AAPL_NAMESPACE\n" "#endif /* _AAPL_RESIZE_H */\n" ); return 0; } #ifdef _____OUTPUT_____ int(1): 999 hex(1): 0xaAFF99 float(1): 99.99 literal(2): lksdj literal(8): literal hex(8): 0x00aba ident(8): foobardd symbol(8): . ident(8): ddsf hex(8): 0x0 symbol(8): . int(8): 9 ACCEPT ident(1): wordwithnum00asdf int(2): 000 ident(2): wordfollowsnum symbol(2): , ident(2): makes ident(2): new ident(2): symbol ident(4): finishing ident(4): early FAIL symbol(8): # ident(8): define ident(8): _AAPL_RESIZE_H symbol(10): # ident(10): include symbol(10): < ident(10): assert symbol(10): . ident(10): h symbol(10): > symbol(12): # ident(12): ifdef ident(12): AAPL_NAMESPACE ident(13): namespace ident(13): Aapl symbol(13): { symbol(14): # ident(14): endif symbol(15): # ident(15): define ident(15): LIN_DEFAULT_STEP int(15): 256 symbol(16): # ident(16): define ident(16): EXPN_UP symbol(16): ( ident(16): existing symbol(16): , ident(16): needed symbol(16): ) symbol(16): \ ident(17): need symbol(17): > ident(17): eng symbol(17): ? symbol(17): ( ident(17): ned symbol(17): < symbol(17): < int(17): 1 symbol(17): ) symbol(17): : ident(17): eing symbol(21): # ident(21): undef ident(21): EXPN_UP symbol(22): # ident(22): ifdef ident(22): AAPL_NAMESPACE symbol(23): # ident(23): endif ACCEPT #endif ragel-6.10/test/include2.rl0000664000175000017500000000113413065111230012467 00000000000000/* * @LANG: c */ #include #include %%{ machine include_test_4; action NonRef3 {printf(" nr3");} a3 = 'a'@{printf(" a3");}; b3 = 'b'@{printf(" b3");}; }%% %%{ machine include_test_1; include "include1.rl"; include include_test_2 "include1.rl"; include include_test_4; main := a1 b1 @NonRef1 a2 b2 @NonRef2 a3 b3 @NonRef3 0 @{fbreak;}; }%% %% write data; void test( char *p ) { int cs; %% write init; %% write exec noend; printf("\n"); } int main() { test( "ababab" ); return 0; } #ifdef _____OUTPUT_____ a1 b1 nr1 a2 b2 nr2 a3 b3 nr3 #endif ragel-6.10/test/range.rl0000664000175000017500000000166713065111230012071 00000000000000/* * @LANG: c */ #include #include struct range { int cs; }; %%{ machine range; variable cs fsm->cs; main := ( 'a' .. 'c' | 'c' .. 'e' | 'm' .. 'n' | 'a' .. 'z' ) '\n'; }%% %% write data; void range_init( struct range *fsm ) { %% write init; } void range_execute( struct range *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int range_finish( struct range *fsm ) { if ( fsm->cs == range_error ) return -1; if ( fsm->cs >= range_first_final ) return 1; return 0; } struct range fsm; void test( char *buf ) { int len = strlen( buf ); range_init( &fsm ); range_execute( &fsm, buf, len ); if ( range_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "a\n" ); test( "z\n" ); test( "g\n" ); test( "no\n" ); test( "1\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT ACCEPT FAIL FAIL #endif ragel-6.10/test/scan4.rl0000664000175000017500000000063713065111230012001 00000000000000/* * @LANG: indep */ ptr ts; ptr te; int act; int token; %% %%{ machine scanner; # Warning: changing the patterns or the input string will affect the # coverage of the scanner action types. main := |* 'a' => { prints "pat1\n"; }; [ab]+ . 'c' => { prints "pat2\n"; }; any; *|; }%% /* _____INPUT_____ "ba a" _____INPUT_____ */ /* _____OUTPUT_____ pat1 pat1 ACCEPT _____OUTPUT_____ */ ragel-6.10/test/recdescent2.rl0000664000175000017500000000375513065111230013176 00000000000000/* * @LANG: java */ class recdescent2 { %%{ machine recdescent; prepush { if ( top == stack_size ) { System.out.print( "growing stack\n" ); stack_size = top * 2; // Don't actually bother to resize here, but we do print messages. //stack = (int*)realloc( stack, sizeof(int)*stack_size ); } } postpop { if ( stack_size > (top * 4) ) { stack_size = top * 2; // Don't actually bother to resize here, but we do print messages. //stack = (int*)realloc( stack, sizeof(int)*stack_size ); System.out.print( "shrinking stack\n" ); } } action item_start { item = p; } action item_finish { String item_data = new String ( data, item, p-item ); System.out.print( "item: " ); System.out.print( item_data ); System.out.print( "\n" ); } action call_main { System.out.print( "calling main\n" ); fcall main; } action return_main { if ( top == 0 ) { System.out.print( "STRAY CLOSE\n" ); fbreak; } System.out.print( "returning from main\n" ); fhold; fret; } id = [a-zA-Z_]+; number = [0-9]+; ws = [ \t\n]+; main := ( ws | ( number | id ) >item_start %item_finish | '{' @call_main '}' | '}' @return_main )**; }%% %% write data; static void test( char data[] ) { int cs, p = 0, pe = data.length, eof = data.length, item = 0; int stack[] = new int[1024]; int stack_size = 1; int top; %% write init; %% write exec; if ( cs == recdescent_error ) System.out.println( "SCANNER ERROR" ); } public static void main( String args[] ) { test( "88 foo { 99 {{{{}}}}{ } }".toCharArray() ); test( "76 } sadf".toCharArray() ); } } /* _____OUTPUT_____ item: 88 item: foo calling main item: 99 calling main growing stack calling main growing stack calling main calling main growing stack returning from main returning from main returning from main returning from main shrinking stack calling main returning from main returning from main shrinking stack item: 76 STRAY CLOSE */ ragel-6.10/test/cppscan6.rl0000664000175000017500000001145113065111230012502 00000000000000/* * @LANG: indep * * const char *data = ts; * int len = te - ts; * cout << "<" << tok << "> "; * for ( int i = 0; i < len; i++ ) * cout << data[i]; * cout << '\n'; */ ptr ts; ptr te; int act; int token; %% %%{ machine scanner; action comment { token = 242; prints "<"; printi token; prints "> "; print_token; prints "\n"; } main := |* # Single and double literals. ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) => { token = 193; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) => { token = 192; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Identifiers ( [a-zA-Z_] [a-zA-Z0-9_]* ) =>{ token = 195; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) => { token = 194; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Integer decimal. Leading part buffered by float. ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) => { token = 218; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Integer octal. Leading part buffered by float. ( '0' [0-9]+ [ulUL]? ) => { token = 219; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Integer hex. Leading 0 buffered by float. ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) => { token = 220; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Only buffer the second item, first buffered by symbol. '::' => { token = 197; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '==' => { token = 223; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '!=' => { token = 224; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '&&' => { token = 225; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '||' => { token = 226; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '*=' => { token = 227; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '/=' => { token = 228; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '%=' => { token = 229; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '+=' => { token = 230; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '-=' => { token = 231; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '&=' => { token = 232; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '^=' => { token = 233; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '|=' => { token = 234; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '++' => { token = 212; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '--' => { token = 213; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '->' => { token = 211; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '->*' => { token = 214; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; '.*' => { token = 215; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Three char compounds, first item already buffered. '...' => { token = 240; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Single char symbols. ( punct - [_"'] ) => { token = (first_token_char); prints "<"; printi token; prints "> "; print_token; prints "\n"; }; # Comments and whitespace. '/!' ( any* $0 '!/' @1 ) => comment; '//' ( any* $0 '\n' @1 ) => comment; ( any - 33..126 )+ => { token = 241; prints "<"; printi token; prints "> "; print_token; prints "\n"; }; *|; }%% /* _____INPUT_____ "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" "'\n'\n" _____INPUT_____ */ /* _____OUTPUT_____ <192> "\"hi" <241> <242> /! !/ <241> <218> 44 <241> <194> .44 <241> <194> 44. <241> <218> 44 <241> <218> 44 <241> <46> . <241> <218> 44 <241> <194> 44.44 <241> <195> _hithere22 ACCEPT <193> '\'' <192> "\n\d'\"" <241> <195> hi <241> <218> 99 <241> <194> .99 <241> <194> 99e-4 <241> <214> ->* <241> <226> || <241> <220> 0x98 <241> <218> 0 <195> x <241> <242> // <242> /! * !/ ACCEPT FAIL _____OUTPUT_____ */ ragel-6.10/test/xmlcommon.rl0000664000175000017500000001277413065111230013007 00000000000000/* * This file is included by xml.rl * * @IGNORE: yes */ %%{ # # Common XML grammar rules based on the XML 1.0 BNF from: # http://www.jelks.nu/XML/xmlebnf.html # machine CommonXml; S = (0x20 | 0x9 | 0xD | 0xA)+; # WAS PubidChar = 0x20 | 0xD | 0xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]; PubidChar = 0x20 | 0xD | 0xA | [a-zA-Z0-9] | [\-'()+,./:=?;!*#@$_%]; PubidLiteral = '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"; Name = (Letter | '_' | ':') (NameChar)*; Comment = ''; # Used strong subtraction operator, and replaced * with +. Ragel complained since using # * results in a machine that accepts 0 length strings, and later it's only used in an # optional construct anyway. # CharData_Old = [^<&]* - ([^<&]* ']]>' [^<&]*); CharData = [^<&]+ -- ']]>'; SystemLiteral = ('"' [^"]* '"') | ("'" [^']* "'"); Eq = S? '=' S?; VersionNum = ([a-zA-Z0-9_.:] | '-')+; # WAS S 'version' Eq (' VersionNum ' | " VersionNum ") - fixed quotes VersionInfo = S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"'); ExternalID = 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral; PublicID = 'PUBLIC' S PubidLiteral; NotationDecl = ''; EncName = [A-Za-z] ([A-Za-z0-9._] | '-')*; EncodingDecl = S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ); # UNUSED TextDecl = ''; NDataDecl = S 'NDATA' S Name; PEReference = '%' Name ';'; EntityRef = '&' Name ';'; CharRef = '&#' [0-9]+ ';' | '&0x' [0-9a-fA-F]+ ';'; Reference = EntityRef | CharRef; EntityValue = '"' ([^%&"] | PEReference | Reference)* '"' | "'" ([^%&'] | PEReference | Reference)* "'"; PEDef = EntityValue | ExternalID; EntityDef = EntityValue | (ExternalID NDataDecl?); PEDecl = ''; GEDecl = ''; EntityDecl = GEDecl | PEDecl; Mixed = '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'; # WAS cp = (Name | choice | seq) ('?' | '*' | '+')?; # WAS seq = '(' S? cp ( S? ',' S? cp )* S? ')'; # WAS choice = '(' S? cp ( S? '|' S? cp )* S? ')'; # WAS children = (choice | seq) ('?' | '*' | '+')?; # TODO put validation for this in and make it clearer alt = '?' | '*' | '+'; children = '(' S? ( ( Name alt? ) | '(' | ( ')' alt? ) | [,|] | S ) ')' alt?; contentspec = 'EMPTY' | 'ANY' | Mixed | children; elementdecl = ''; AttValue = '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"; Attribute = Name Eq AttValue; Nmtoken = (NameChar)+; # UNUSED Nmtokens = Nmtoken (S Nmtoken)*; Enumeration = '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'; NotationType = 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'; EnumeratedType = NotationType | Enumeration; TokenizedType = 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'; StringType = 'CDATA'; AttType = StringType | TokenizedType | EnumeratedType; DefaultDecl = '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue); AttDef = S Name S AttType S DefaultDecl; AttlistDecl = ''; EmptyElemTag = '<' Name (S Attribute)* S? '/>'; ETag = ''; PITarget_Old = Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')); PITarget = Name -- "xml"i; PI = '' Char*)))? '?>'; markupdecl = elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment; doctypedecl = ''; # TODO extSubsetDecl = ( markupdecl | conditionalSect | PEReference | S )*; # UNUSED extSubsetDecl = ( markupdecl | PEReference | S )*; # UNUSED extSubset = TextDecl? extSubsetDecl; # UNUSED Ignore = Char* - (Char* ('') Char*); # TODO: ignoreSectContents = Ignore ('' Ignore)*; # UNUSED ignoreSectContents = Ignore ('' Ignore)*; # UNUSED ignoreSect = ''; # UNUSED includeSect = ''; # UNUSED conditionalSect = includeSect | ignoreSect; STag = '<' Name (S Attribute)* S? '>'; CDStart = ''; # WAS CData = (Char* - (Char* ']]>' Char*)); CData = (Char* -- CDEnd); CDSect = CDStart CData CDEnd; # UNUSED Subcode = ([a-z] | [A-Z])+; # UNUSED UserCode = ('x' | 'X') '-' ([a-z] | [A-Z])+; # UNUSED IanaCode = ('i' | 'I') '-' ([a-z] | [A-Z])+; # UNUSED ISO639Code = ([a-z] | [A-Z]) ([a-z] | [A-Z]); # UNUSED Langcode = ISO639Code | IanaCode | UserCode; # UNUSED LanguageID = Langcode ('-' Subcode)*; SDDecl = S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')); # UNUSED extPE = TextDecl? extSubsetDecl; Misc = Comment | PI | S; XMLDecl = ''; prolog = XMLDecl? Misc* (doctypedecl Misc*)?; # UNUSED Names = Name (S Name)*; # Added fcall - TODO check logic is correct # UNUSED extParsedEnt = TextDecl? @{fcall content;}; # TODO tag stack validation # WAS element = EmptyElemTag | STag content ETag # WAS content = (element | CharData | Reference | CDSect | PI | Comment)*; content = (EmptyElemTag | STag | ETag | CharData | Reference | CDSect | PI | Comment)*; # WAS document = prolog element Misc*; document = prolog ( EmptyElemTag | ( STag content ETag ) ) Misc*; main := document; }%% ragel-6.10/test/call2.rl0000664000175000017500000000407713065111230011770 00000000000000/* * @LANG: c++ */ #include #include int num = 0; struct CallTest { int cs, top, stack[32]; // 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 CallTest; action check_num { if ( num & 1 ) fcall *fentry(odd); else fcall even; } # Test call and return functionality. even := 'even' any @{fhold; fret;}; odd := 'odd' any @{fhold; fret;}; num = [0-9]+ ${ num = num * 10 + (fc - '0'); }; even_odd = num ' ' @check_num "\n"; # Test calls in out actions. fail := !(any*); out_acts = 'OA ok\n' | 'OA error1\n' | 'OA error2\n'; main := even_odd | out_acts; }%% %% write data; void CallTest::init( ) { num = 0; %% write init; } void CallTest::execute( const char *data, int len ) { const char *p = data; const char *pe = data+len; %% write exec; } int CallTest::finish( ) { if ( this->cs == CallTest_error ) return -1; if ( this->cs >= CallTest_first_final ) return 1; return 0; } #define BUFSIZE 1024 void test( const char *buf ) { CallTest test; test.init(); test.execute( buf, strlen(buf) ); if ( test.finish() > 0 ) printf( "ACCEPT\n" ); else printf( "FAIL\n" ); } int main() { test( "78 even\n" ); test( "89 odd\n" ); test( "1 even\n" ); test( "0 odd\n" ); test( "OA ok\n" ); test( "OA error1\n" ); test( "OA error2\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT FAIL FAIL ACCEPT ACCEPT ACCEPT #endif ragel-6.10/test/testcase.txl0000664000175000017500000000620513065111230012773 00000000000000comments '# end comments tokens union "\[[(\\\c)#\]]*\]" end tokens compounds '%% '%%{ '}%% '== ':= '-> '<> '>= '<= '=> '|* '*| '>! '! '>/ '/ end compounds keys 'int 'bool 'true 'false 'char 'ptr 'if 'else 'printi 'prints 'printb 'print_token 'fc 'fpc 'fbreak 'fgoto 'fcall 'fret 'fhold 'fexec 'machine 'alphtype 'action 'first_token_char end keys define lang_indep [al_statements] '%% [NL] [al_statements] [ragel_def] end define define ragel_def '%%{ [NL] [IN] [ragel_program] [EX] '}%% [NL] end define define ragel_program [repeat statement] end define define statement [machine_stmt] | [alphtype_stmt] | [action_stmt] | [cond_action_stmt] | [machine_def] | [machine_inst] end define define machine_stmt 'machine [id] '; [NL] end define define alphtype_stmt 'alphtype [repeat id] '; [NL] end define define action_stmt 'action [id] [al_host_block] end define define cond_action_stmt 'action [id] '{ [al_expr] '} [NL] end define define al_statements [repeat action_lang_stmt] end define define action_lang_stmt [al_ragel_stmt] | [al_variable_decl] | [al_expr_stmt] | [al_if_stmt] | [al_print_stmt] | '{ [al_statements] '} end define define al_print_stmt [print_cmd] [al_expr] '; [NL] | 'print_token '; [NL] end define define print_cmd 'printi | 'prints | 'printb end define define al_variable_decl [al_type_decl] [id] [opt union] '; [NL] end define define al_array_decl '[ [number] '] end define define al_type_decl 'int | 'bool | 'char | 'ptr end define define al_expr_stmt [al_expr] '; [NL] end define define al_expr [al_term] [repeat al_expr_extend] end define define al_expr_extend [al_expr_op] [al_term] end define define al_expr_op '= | '+ | '- | '* | '/ | '== | '<= | '>= | '< | '> end define define al_term [al_term_base] [opt union] end define define al_term_base [id] | [SPOFF] [id] '( [SPON] [al_expr] ') | [opt al_sign] [number] | [stringlit] | [charlit] | 'fc | 'true | 'false | '( [al_expr] ') | '< [SPOFF] [al_type_decl] '> '( [SPON] [al_expr] ') | 'first_token_char end define define al_sign '- | '+ end define define al_if_stmt 'if '( [al_expr] ') [NL] [IN] [action_lang_stmt] [EX] [opt al_else] end define define al_else 'else [NL] [IN] [action_lang_stmt] [EX] end define define al_ragel_stmt 'fbreak '; [NL] | 'fhold '; [NL] | 'fexec [repeat al_expr] '; [NL] | 'fnext [id] '; [NL] | 'fgoto [id] '; [NL] | 'fcall [id] '; [NL] | 'fnext '* [repeat al_expr] '; [NL] | 'fgoto '* [repeat al_expr] '; [NL] | 'fcall '* [repeat al_expr] '; [NL] | 'fret '; [NL] end define define machine_def [id] '= [machine_expr] '; [NL] end define define machine_inst [id] ':= [machine_expr] '; [NL] end define define machine_expr [repeat machine_expr_item] end define define scanner_item [repeat machine_expr_item] '; [NL] end define define machine_expr_item [action_embed] [al_host_block] | '|* [repeat scanner_item] '*| | [not ';] [not '*|] [token] end define define al_host_block '{ [NL] [IN] [al_statements] [EX] '} [NL] end define define action_embed '> | '$ | '@ | '% | '$! | '=> end define ragel-6.10/test/cppscan5.rl0000664000175000017500000001154113065111230012501 00000000000000/* * @LANG: d */ /* * Test in and out state actions. */ import std.c.stdio; import std.string; static const int TK_Dlit = 192; static const int TK_Slit = 193; static const int TK_Float = 194; static const int TK_Id = 195; static const int TK_NameSep = 197; static const int TK_Arrow = 211; static const int TK_PlusPlus = 212; static const int TK_MinusMinus = 213; static const int TK_ArrowStar = 214; static const int TK_DotStar = 215; static const int TK_ShiftLeft = 216; static const int TK_ShiftRight = 217; static const int TK_IntegerDecimal = 218; static const int TK_IntegerOctal = 219; static const int TK_IntegerHex = 220; static const int TK_EqualsEquals = 223; static const int TK_NotEquals = 224; static const int TK_AndAnd = 225; static const int TK_OrOr = 226; static const int TK_MultAssign = 227; static const int TK_DivAssign = 228; static const int TK_PercentAssign = 229; static const int TK_PlusAssign = 230; static const int TK_MinusAssign = 231; static const int TK_AmpAssign = 232; static const int TK_CaretAssign = 233; static const int TK_BarAssign = 234; static const int TK_DotDotDot = 240; static const int TK_Whitespace = 241; static const int TK_Comment = 242; class Scanner { int cs, act; char *ts, te; void token( int tok ) { char *data = ts; int len = te - ts; printf( "<%i> ", tok ); for ( int i = 0; i < len; i++ ) printf( "%c", data[i] ); printf( "\n" ); } %%{ machine Scanner; main := |* # Single and double literals. ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) => { token( TK_Slit );}; ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) => { token( TK_Dlit );}; # Identifiers ( [a-zA-Z_] [a-zA-Z0-9_]* ) =>{ token( TK_Id );}; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) => { token( TK_Float );}; # Integer decimal. Leading part buffered by float. ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) => { token( TK_IntegerDecimal );}; # Integer octal. Leading part buffered by float. ( '0' [0-9]+ [ulUL]{0,2} ) => { token( TK_IntegerOctal );}; # Integer hex. Leading 0 buffered by float. ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) => { token( TK_IntegerHex );}; # Only buffer the second item, first buffered by symbol. */ '::' => {token( TK_NameSep );}; '==' => {token( TK_EqualsEquals );}; '!=' => {token( TK_NotEquals );}; '&&' => {token( TK_AndAnd );}; '||' => {token( TK_OrOr );}; '*=' => {token( TK_MultAssign );}; '/=' => {token( TK_DivAssign );}; '%=' => {token( TK_PercentAssign );}; '+=' => {token( TK_PlusAssign );}; '-=' => {token( TK_MinusAssign );}; '&=' => {token( TK_AmpAssign );}; '^=' => {token( TK_CaretAssign );}; '|=' => {token( TK_BarAssign );}; '++' => {token( TK_PlusPlus );}; '--' => {token( TK_MinusMinus );}; '->' => {token( TK_Arrow );}; '->*' => {token( TK_ArrowStar );}; '.*' => {token( TK_DotStar );}; # Three char compounds, first item already buffered. */ '...' => { token( TK_DotDotDot );}; # Single char symbols. ( punct - [_"'] ) => { token( ts[0] );}; action comment { token( TK_Comment ); } # Comments and whitespace. '/*' ( any* $0 '*/' @1 ) => comment; '//' ( any* $0 '\n' @1 ) => comment; ( any - 33..126 )+ => { token( TK_Whitespace );}; *|; }%% %% write data noprefix; void init( ) { %% write init; } void execute( char* data, int len ) { char *p = data; char *pe = data + len; char *eof = pe; %% write exec; } // 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( ) { if ( cs == error ) return -1; if ( cs >= first_final ) return 1; return 0; } }; static const int BUFSIZE = 12; void test( char buf[] ) { Scanner scanner = new Scanner(); scanner.init(); scanner.execute( buf.ptr, buf.length ); if ( scanner.cs == Scanner.error ) { /* Machine failed before finding a token. */ printf("PARSE ERROR\n"); } scanner.finish(); return 0; } int main() { test( "\"\\\"hi\" /*\n" "*/\n" "44 .44\n" "44. 44\n" "44 . 44\n" "44.44\n" "_hithere22" ); test( "'\\''\"\\n\\d'\\\"\"\n" "hi\n" "99\n" ".99\n" "99e-4\n" "->*\n" "||\n" "0x98\n" "0x\n" "//\n" "/* * */" ); test( "'\n" "'\n" ); return 0; } /+ _____OUTPUT_____ <192> "\"hi" <241> <242> /* */ <241> <218> 44 <241> <194> .44 <241> <194> 44. <241> <218> 44 <241> <218> 44 <241> <46> . <241> <218> 44 <241> <194> 44.44 <241> <195> _hithere22 <193> '\'' <192> "\n\d'\"" <241> <195> hi <241> <218> 99 <241> <194> .99 <241> <194> 99e-4 <241> <214> ->* <241> <226> || <241> <220> 0x98 <241> <218> 0 <195> x <241> <242> // <242> /* * */ PARSE ERROR +++++++++++++++++++/ ragel-6.10/test/union.rl0000664000175000017500000000676013065111230012124 00000000000000/* * @LANG: c++ * Show off concurrent abilities. */ #include #include #include #include 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; start_word = 0; start_comment = 0; start_literal = 0; %% write init; } void Concurrent::execute( const char *data, int len ) { const char *p = data; const char *pe = data + len; const char *eof = pe; %% write exec; } int Concurrent::finish( ) { if ( cs == Concurrent_error ) return -1; if ( cs >= Concurrent_first_final ) return 1; return 0; } void test( const 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 ragel-6.10/test/high1.rl0000664000175000017500000000550613065111230011771 00000000000000/* * @LANG: c * @ALLOW_GENFLAGS: -T0 -T1 -G0 -G1 -G2 */ /** * Test a high character to make sure signedness * isn't messing us up. */ #include #include #include struct high { int cs; }; %%{ machine high; variable cs fsm->cs; # We Want the header portion. alphtype unsigned int; main := ( 0x20 .. 0xefffffff @1 @{printf("gothigh1\n");} | 0xf0000000 @1 @{printf("gothigh1\n");} | 0x200 .. 0xfe000000 @1 @{printf("gothigh2\n");} | any @0 @{printf("else\n");} )*; }%% %% write data; void high_init( struct high *fsm ) { %% write init; } void high_execute( struct high *fsm, const unsigned int *_data, int _len ) { const unsigned int *p = _data; const unsigned int *pe = _data+_len; %% write exec; } int high_finish( struct high *fsm ) { if ( fsm->cs == high_error ) return -1; if ( fsm->cs >= high_first_final ) return 1; return 0; } struct high high; #define BUFSIZE 1024 char cbuf[BUFSIZE]; unsigned int buf[BUFSIZE]; int buflen = 0; char numbuf[9]; int numlen = 0; struct tokenizer { int cs; }; %%{ machine tokenizer; variable cs fsm->cs; action bufdigit { if ( numlen < 8 ) numbuf[numlen++] = fc; } action writeDigit { /* Null terminate the buffer storing the number and reset. */ numbuf[numlen] = 0; numlen = 0; /* Store the number in the buf. If the buf is full then * flush and reset the buffer. */ buf[buflen++] = strtoul( numbuf, 0, 16 ); if ( buflen == BUFSIZE ) { high_execute( &high, buf, BUFSIZE ); buflen = 0; } } action finish { if ( buflen > 0 ) high_execute( &high, buf, buflen ); if ( high_finish( &high ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } num = ( digit | 'a'..'f' )+ $bufdigit %writeDigit; main := ( num $1 %0 | space )* %/finish; }%% %% write data; void tokenizer_init( struct tokenizer *fsm ) { %% write init; } void tokenizer_execute( struct tokenizer *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; const char *eof = pe; %% write exec; } int tokenizer_finish( struct tokenizer *fsm ) { if ( fsm->cs == tokenizer_error ) return -1; if ( fsm->cs >= tokenizer_first_final ) return 1; return 0; } struct tokenizer tok; void test( char *cbuf ) { int len = strlen( cbuf ); high_init( &high ); tokenizer_init( &tok ); tokenizer_execute( &tok, cbuf, len ); if ( tokenizer_finish( &tok ) <= 0 ) printf("Tokenizer FAIL\n"); } char data[] = "10 20 30 40 50 200 300 400 \n" "d0000000 f0000000 fd000000 fe000000\n" "ff000000 ffffffffffffffffffffffffff\n" "ff\n"; int main() { test( data ); return 0; } #ifdef _____OUTPUT_____ else gothigh1 gothigh1 gothigh1 gothigh1 gothigh1 gothigh2 gothigh1 gothigh2 gothigh1 gothigh2 gothigh1 gothigh2 gothigh1 gothigh2 gothigh2 gothigh2 else else gothigh1 ACCEPT #endif ragel-6.10/test/high2.rl0000664000175000017500000000347613065111230011776 00000000000000/* * @LANG: c++ */ /** * Test a high character to make sure signedness * isn't messing us up. */ #include #include struct Fsm { 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. int 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. int execute( const unsigned 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 Fsm; alphtype unsigned char; # Indicate we got the high character. action gothigh { printf("yes\n"); } main := 0xe8 @gothigh '\n'; }%% %% write data; int Fsm::init( ) { %% write init; return 0; } int Fsm::execute( const unsigned char *_data, int _len ) { const unsigned char *p = _data; const unsigned char *pe = _data+_len; %% write exec; if ( cs == Fsm_error ) return -1; if ( cs >= Fsm_first_final ) return 1; return 0; } int Fsm::finish() { if ( cs == Fsm_error ) return -1; if ( cs >= Fsm_first_final ) return 1; return 0; } Fsm fsm; void test( unsigned char *buf, int len ) { fsm.init(); fsm.execute( buf, len ); if ( fsm.finish() > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } unsigned char data1[] = { 0xe8, 10 }; unsigned char data2[] = { 0xf8, 10 }; int main() { test( data1, 2 ); test( data2, 2 ); return 0; } #ifdef _____OUTPUT_____ yes ACCEPT FAIL #endif ragel-6.10/test/strings1.rl0000664000175000017500000000543513065111230012544 00000000000000/* * @LANG: c */ #include #include struct strs { int cs; }; %%{ machine strs; variable cs fsm->cs; main := "__gmon_start__\n" | "cerr\n" | "__cp_push_exception\n" | "_DYNAMIC\n" | "__rtti_user\n" | "__rtti_si\n" | "_init\n" | "__throw\n" | "__deregister_frame_info\n" | "terminate__Fv\n" | "__builtin_vec_new\n" | "_fini\n" | "__builtin_vec_delete\n" | "_GLOBAL_OFFSET_TABLE_\n" | "__nw__FUiPv\n" | "__builtin_delete\n" | "__builtin_new\n" | "cout\n" | "__register_frame_info\n" | "__eh_alloc\n" | "strcpy\n" | "stdout\n" | "memmove\n" | "memcpy\n" | "malloc\n" | "isatty\n" | "strtoul\n" | "fprintf\n" | "stdin\n" | "ferror\n" | "strncpy\n" | "unlink\n" | "strcasecmp\n" | "realloc\n" | "_IO_getc\n" | "fread\n" | "memset\n" | "__assert_fail\n" | "strcmp\n" | "stderr\n" | "fwrite\n" | "exit\n" | "fopen\n" | "atoi\n" | "fileno\n" | "_IO_stdin_used\n" | "__libc_start_main\n" | "strlen\n" | "free\n" | "_edata\n" | "__bss_start\n" | "_end\n" | "QVhl\n" | "BPPh\n" | "PHRV\n" | "PHRj\n" | "PHRj\n" | "jphy\n" | "jqhy\n" | "PHRj\n" | "PHRj\n" | "LWVS\n" | "LWVS\n" | "bad_alloc\n" | "main\n" | "false\n" | "help\n" | "bad_alloc\n" | "bad_alloc\n" | "bad_alloc\n" | "ascii\n" | "extend\n" | "alnum\n" | "alpha\n" | "cntrl\n" | "digit\n" | "graph\n" | "lower\n" | "print\n" | "punct\n" | "space\n" | "upper\n" | "xdigit\n" | "false\n" | "bad_alloc\n" | "bad_alloc\n" | "bad_alloc\n" | "TransStruct\n" | "StateStruct\n" | "Struct\n" | "Init\n" | "bad_alloc\n" | "TransStruct\n" | "StateStruct\n" | "Struct\n" | "Init\n" | "Accept\n" | "Finish\n" | "bad_alloc\n" | "Struct\n" | "Init\n" | "Finish\n" | "Accept\n" | "bad_alloc\n" | "Struct\n" | "Init\n" | "bad_alloc\n" | "Struct\n" | "Init\n" | "Finish\n" | "Accept\n" | "bad_alloc\n" | "Struct\n" | "Init\n" | "Finish\n" | "Accept"; }%% %% write data; void strs_init( struct strs *fsm ) { %% write init; } void strs_execute( struct strs *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int strs_finish( struct strs *fsm ) { if ( fsm->cs == strs_error ) return -1; if ( fsm->cs >= strs_first_final ) return 1; return 0; } struct strs fsm; void test( char *buf ) { int len = strlen( buf ); strs_init( &fsm ); strs_execute( &fsm, buf, len ); if ( strs_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "stdin\n" ); test( "bad_alloc\n" ); test( "_GLOBAL_OFFSET_TABLE_\n" ); test( "not in\n" ); test( "isatty\n" "junk on end.\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT ACCEPT FAIL FAIL #endif ragel-6.10/test/import1.rl0000664000175000017500000000143213065111230012356 00000000000000/* * @LANG: c */ #include char *foo = "foo"; char b = 98; char a = 97; char r = 114; #define SP 32 #define NL '\n' %%{ machine tmp; import "import1.rl"; foobar = foo @{printf("foo\n"); } | b a r @{printf("bar\n");}; main := ( foobar SP foobar NL )*; }%% %% write data; int cs; void exec_str( char *p, int len ) { char *pe = p + len; %% write exec; } void exec_c( char c ) { exec_str( &c, 1 ); } int main() { %% write init; exec_str( foo, 3 ); exec_c( SP ); exec_c( b ); exec_c( a ); exec_c( r ); exec_c( NL ); exec_c( b ); exec_c( a ); exec_c( r ); exec_c( SP ); exec_str( foo, 3 ); exec_c( NL ); if ( cs < tmp_first_final ) printf("FAIL\n"); else printf("ACCEPT\n"); return 0; } #ifdef _____OUTPUT_____ foo bar bar foo ACCEPT #endif ragel-6.10/test/mailbox1.rl0000664000175000017500000001215713065111230012505 00000000000000/* * @LANG: c++ * @CFLAGS: -I../aapl * * Test works with split code gen. */ /* * Parses unix mail boxes into headers and bodies. */ #include "mailbox1.h" %%{ machine MBox; # Buffer the header names. action bufHeadName { fsm->headName.append(fc); } # Buffer the header content. action bufHeadContent { fsm->headContent.append(fc); } # Terminate a header. If it is an interesting header then prints it. action finBufHeadContent { /* Terminate the buffers. */ fsm->headName.append(0); fsm->headContent.append(0); /* Print the header. Interesting headers. */ printf("%s:%s\n", fsm->headName.data, fsm->headContent.data); /* Clear for the next time we use them. */ fsm->headName.empty(); fsm->headContent.empty(); } action msgstart{ printf("NEW MESSAGE\n"); } # Prints a blank line after the end of the headers of each message. action blankLine { printf("\n"); } # Helpers we will use in matching the date section of the from line. day = /[A-Z][a-z][a-z]/; month = /[A-Z][a-z][a-z]/; year = /[0-9][0-9][0-9][0-9]/; time = /[0-9][0-9]:[0-9][0-9]/ . ( /:[0-9][0-9]/ | '' ); letterZone = /[A-Z][A-Z][A-Z]/; numZone = /[+\-][0-9][0-9][0-9][0-9]/; zone = letterZone | numZone; dayNum = /[0-9 ][0-9]/; # These are the different formats of the date minus an obscure # type that has a funny string 'remote from xxx' on the end. Taken # from c-client in the imap-2000 distribution. date = day . ' ' . month . ' ' . dayNum . ' ' . time . ' ' . ( year | year . ' ' . zone | zone . ' ' . year ); # Note the priority assignment on the end of the from line. While we # matching the body of a message we may enter into this machine. We will # not leave the body of the previous message until this entire from line is # matched. fromLine = 'From ' . /[^\n]/* . ' ' . date . '\n' @(new_msg,1) @msgstart; # The types of characters that can be used as a header name. hchar = print - [ :]; header = # The name of the header. hchar+ $bufHeadName . ':' # The content of the header. Look out for continuations. . ( (extend - '\n') $bufHeadContent | '\n'. [ \t] @bufHeadContent )* # Buffer must end with a newline that does not continue. . '\n' %finBufHeadContent; messageLine = ( extend - '\n' )* . '\n' @(new_msg, 0); # When we get to the last newline we are still matching messageLine # so on the last newline it will think we are still in the message. # We need this because we can't assume that every newline means # the end of the current message, whereas at the same time we requre # that there be a newline before the fromLine of the next message. message = ( fromLine . header* . '\n' @blankLine . messageLine* . '\n' ); # Its important that the priority in the fromLine gets bumped up # so that we are able to move to new messages. Otherwise we # will always stay in the message body of the first message. main := message*; }%% %% write data; void MBox::init( ) { MBox *fsm = this; %% write init; } void MBox::execute( const char *data, int len ) { MBox *fsm = this; const char *p = data; const char *pe = data + len; %%{ access fsm->; write exec; }%% } int MBox::finish( ) { if ( cs == MBox_error ) return -1; if ( cs >= MBox_first_final ) return 1; return 0; } MBox mbox; void test( const char *buf ) { int len = strlen( buf ); mbox.init(); mbox.execute( buf, len ); if ( mbox.finish() > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "From email address goes here Wed Nov 28 13:30:05 2001 -0500\n" "Header1: this is the header contents\n" " there is more on the second line\n" " and more on the third line.\n" "Header2: slkdj\n" "\n" "This is the message data\n" "\n" "From email Wed Nov 28 13:30:05 2001 -0500\n" "Header: \n" "\n" "mail message\n" "\n" ); test( "From user@host.dom Wed Nov 28 13:30:05 2001\n" "\n" "There are no headers. \n" "\n" "From email Wed Nov 28 13:30:05 EST 2000\n" "\n" "There are no headers.\n" "\n" ); test( "From user@host.dom Wed Nov 28 13:30:05 2001\n" "Header:alsdj\n" "\n" "Header:\n" "salkfj\n" "\n" "There are no headers. \n" "\n" ); test( "From user@host.dom Wed Nov 28 13:30:05 2001\n" "Header:alsdj\n" "\n" "Header:\n" "salkfj\n" "\n" "There are no headers. \n" "\n" ">From user@host.dom Wed Nov 28 13:30:05 2001\n" "\n" ); test( "From user@host.dom Wed Nov 28 13:30:05 2001\n" "Header:alsdj\n" "\n" "Header:\n" "salkfj\n" "\n" "There are no headers. \n" "\n" "From user@host.dom Wed Nov 28 13:30:05 2001\n" "\n" ); test( "From user@host.dom Wed Nov 28 13:30:05 2001\n" "Header:alsdj\n" "\n" "Header:\n" "salkfj\n" "\n" "There are no headers. \n" "\n" "From user@host.dom Wed Nov 28 13:30:05 2001\n" "\n" "\n" ); return 0; } #ifdef _____OUTPUT_____ NEW MESSAGE Header1: this is the header contents there is more on the second line and more on the third line. Header2: slkdj NEW MESSAGE Header: ACCEPT NEW MESSAGE NEW MESSAGE ACCEPT NEW MESSAGE Header:alsdj ACCEPT NEW MESSAGE Header:alsdj ACCEPT NEW MESSAGE Header:alsdj NEW MESSAGE FAIL NEW MESSAGE Header:alsdj NEW MESSAGE ACCEPT #endif ragel-6.10/test/recdescent1.rl0000664000175000017500000000345013065111230013165 00000000000000/* * @LANG: c * Test growable stack. */ #include #include #include %%{ machine recdescent; prepush { if ( top == stack_size ) { printf( "growing stack\n" ); stack_size = top * 2; stack = (int*)realloc( stack, sizeof(int)*stack_size ); } } postpop { if ( stack_size > (top * 4) ) { stack_size = top * 2; stack = (int*)realloc( stack, sizeof(int)*stack_size ); printf( "shrinking stack\n" ); } } action item_start { item = p; } action item_finish { printf( "item: " ); fwrite( item, 1, p-item, stdout ); printf( "\n" ); } action call_main { printf( "calling main\n" ); fcall main; } action return_main { if ( top == 0 ) { printf( "STRAY CLOSE\n" ); fbreak; } printf( "returning from main\n" ); fhold; fret; } id = [a-zA-Z_]+; number = [0-9]+; ws = [ \t\n]+; main := ( ws | ( number | id ) >item_start %item_finish | '{' @call_main '}' | '}' @return_main )**; }%% %% write data; void test( char *buf ) { int cs; int *stack; int top, stack_size; char *p, *pe, *eof, *item = 0; int len = strlen( buf ); %% write init; stack_size = 1; stack = (int*)malloc( sizeof(int) * stack_size ); p = buf; pe = buf + len; eof = pe; %% write exec; if ( cs == recdescent_error ) { /* Machine failed before finding a token. */ printf( "PARSE ERROR\n" ); } } int main() { test( "88 foo { 99 {{{{}}}}{ } }"); test( "76 } sadf"); return 0; } #ifdef _____OUTPUT_____ item: 88 item: foo calling main item: 99 calling main growing stack calling main growing stack calling main calling main growing stack returning from main returning from main returning from main returning from main shrinking stack calling main returning from main returning from main shrinking stack item: 76 STRAY CLOSE #endif ragel-6.10/test/keller1.rl0000664000175000017500000004167613065111230012340 00000000000000/* * @LANG: c++ */ /* * Automatically generated by keller. Do not edit. * * Parts of this file are copied from Keller source covered by the GNU * GPL. As a special exception, you may use the parts of this file copied * from Keller source without restriction. The remainder is derived from * "tmp.gmr" and inherits the copyright status of that file. */ #line 1 "tmp.gmr" #include using std::cout; using std::endl; #line 16 "tmp.rl" enum token_type_e { tt_id, tt_equals, tt_semi, tt_pipe, tt_amp, tt_minus, tt_dot, tt_colon, tt_percent, tt_dollar, tt_plus, tt_number, tt_star, tt_question, tt_not, tt_andFSM, tt_orFSM, tt_open, tt_close }; struct LangEl { int line, lineEnd; int pos; int type; int state; LangEl *prev, *next; }; struct Token : public LangEl { const char *value; }; struct Lel_start : public LangEl { #line 32 "tmp.gmr" int si; #line 59 "tmp.rl" }; struct Lel_M : public LangEl { #line 36 "tmp.gmr" int mi; #line 67 "tmp.rl" }; #define l__error 19 #define l_tt_id 0 #define l_tt_equals 1 #define l_tt_semi 2 #define l_tt_pipe 3 #define l_tt_amp 4 #define l_tt_minus 5 #define l_tt_dot 6 #define l_tt_colon 7 #define l_tt_percent 8 #define l_tt_dollar 9 #define l_tt_plus 10 #define l_tt_number 11 #define l_tt_star 12 #define l_tt_question 13 #define l_tt_not 14 #define l_tt_andFSM 15 #define l_tt_orFSM 16 #define l_tt_open 17 #define l_tt_close 18 #define l_start 23 #define l_M 24 #define l_A 25 #define l_E 26 #define l_T 27 #define l_N 28 #define l_K 29 #define l_F 30 #define l__start 31 #define l__eof 20 struct LangEl; struct Parser { Parser(); void parseLangEl( LangEl *langEl ); int done( ); void push( LangEl *lel ) { lel->prev = stack; stack = lel; } LangEl *pop() { LangEl *ret = stack; stack = stack->prev; return ret; } int pop( int n ); void rem( LangEl *lel, int n ); LangEl *stack; int next; LangEl *redLel; LangEl *rhs[10]; 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. int 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. int execute( LangEl *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 Parser; getkey fpc->type; action shift { fpc->state = fcurs; push( fpc ); } action pop1 { fnext *pop(1); } action pop2 { fnext *pop(2); } action pop3 { fnext *pop(3); } action pop4 { fnext *pop(4); } action new_error { redLel = new LangEl(); redLel->type = 19; } action newstart { redLel = new Lel_start(); redLel->type = 23; } action newM { redLel = new Lel_M(); redLel->type = 24; } action newA { redLel = new LangEl(); redLel->type = 25; } action newE { redLel = new LangEl(); redLel->type = 26; } action newT { redLel = new LangEl(); redLel->type = 27; } action newN { redLel = new LangEl(); redLel->type = 28; } action newK { redLel = new LangEl(); redLel->type = 29; } action newF { redLel = new LangEl(); redLel->type = 30; } action new_eof { redLel = new LangEl(); redLel->type = 20; } action new_epsilon { redLel = new LangEl(); redLel->type = 21; } action new_null { redLel = new LangEl(); redLel->type = 22; } action rem1 { rem(fpc, 1); } action rem2 { rem(fpc, 2); } action rem3 { rem(fpc, 3); } action rem4 { rem(fpc, 4); } action r_start_0 { #line 41 "tmp.gmr" cout << "start = M;" << endl; static_cast(redLel)->si = static_cast(rhs[0])->mi; #line 214 "tmp.rl" } action r_M_0 { #line 44 "tmp.gmr" cout << "M = M A;" << endl; #line 221 "tmp.rl" } action r_M_1 { #line 45 "tmp.gmr" cout << "M = A;" << endl; #line 228 "tmp.rl" } action r_A_0 { #line 46 "tmp.gmr" cout << "A = tt_id tt_equals E tt_semi;" << endl; #line 235 "tmp.rl" } action r_E_0 { #line 47 "tmp.gmr" cout << "E = E tt_pipe T;" << endl; #line 242 "tmp.rl" } action r_E_1 { #line 48 "tmp.gmr" cout << "E = E tt_amp T;" << endl; #line 249 "tmp.rl" } action r_E_2 { #line 49 "tmp.gmr" cout << "E = E tt_minus T;" << endl; #line 256 "tmp.rl" } action r_E_3 { #line 50 "tmp.gmr" cout << "E = T;" << endl; #line 263 "tmp.rl" } action r_T_0 { #line 51 "tmp.gmr" cout << "T = T tt_dot N;" << endl; #line 270 "tmp.rl" } action r_T_1 { #line 52 "tmp.gmr" cout << "T = T N;" << endl; #line 277 "tmp.rl" } action r_T_2 { #line 53 "tmp.gmr" cout << "T = N;" << endl; #line 284 "tmp.rl" } action r_N_0 { #line 54 "tmp.gmr" cout << "N = N tt_colon tt_id;" << endl; #line 291 "tmp.rl" } action r_N_1 { #line 55 "tmp.gmr" cout << "N = N tt_percent tt_id;" << endl; #line 298 "tmp.rl" } action r_N_2 { #line 56 "tmp.gmr" cout << "N = N tt_dollar tt_id;" << endl; #line 305 "tmp.rl" } action r_N_3 { #line 57 "tmp.gmr" cout << "N = N tt_colon tt_plus tt_number;" << endl; #line 312 "tmp.rl" } action r_N_4 { #line 58 "tmp.gmr" cout << "N = N tt_colon tt_minus tt_number;" << endl; #line 319 "tmp.rl" } action r_N_5 { #line 59 "tmp.gmr" cout << "N = N tt_percent tt_plus tt_number;" << endl; #line 326 "tmp.rl" } action r_N_6 { #line 60 "tmp.gmr" cout << "N = N tt_percent tt_minus tt_number;" << endl; #line 333 "tmp.rl" } action r_N_7 { #line 61 "tmp.gmr" cout << "N = N tt_dollar tt_plus tt_number;" << endl; #line 340 "tmp.rl" } action r_N_8 { #line 62 "tmp.gmr" cout << "N = N tt_dollar tt_minus tt_number;" << endl; #line 347 "tmp.rl" } action r_N_9 { #line 63 "tmp.gmr" cout << "N = K;" << endl; #line 354 "tmp.rl" } action r_K_0 { #line 64 "tmp.gmr" cout << "K = F tt_star;" << endl; #line 361 "tmp.rl" } action r_K_1 { #line 65 "tmp.gmr" cout << "K = F tt_question;" << endl; #line 368 "tmp.rl" } action r_K_2 { #line 66 "tmp.gmr" cout << "K = F tt_plus;" << endl; #line 375 "tmp.rl" } action r_K_3 { #line 67 "tmp.gmr" cout << "K = F;" << endl; #line 382 "tmp.rl" } action r_K_4 { #line 68 "tmp.gmr" cout << "K = tt_not F tt_star;" << endl; #line 389 "tmp.rl" } action r_K_5 { #line 69 "tmp.gmr" cout << "K = tt_not F tt_question;" << endl; #line 396 "tmp.rl" } action r_K_6 { #line 70 "tmp.gmr" cout << "K = tt_not F tt_plus;" << endl; #line 403 "tmp.rl" } action r_K_7 { #line 71 "tmp.gmr" cout << "K = tt_not F;" << endl; #line 410 "tmp.rl" } action r_F_0 { #line 72 "tmp.gmr" cout << "F = tt_andFSM;" << endl; #line 417 "tmp.rl" } action r_F_1 { #line 73 "tmp.gmr" cout << "F = tt_orFSM;" << endl; #line 424 "tmp.rl" } action r_F_2 { #line 74 "tmp.gmr" cout << "F = tt_id;" << endl; #line 431 "tmp.rl" } action r_F_3 { #line 75 "tmp.gmr" cout << "F = tt_open E tt_close;" << endl; #line 438 "tmp.rl" } main := s0: start: ( 23 @shift -> s1 | 25 @shift -> s3 | 24 @shift -> s4 | 0 @shift -> s5 ), s1: ( 20 @shift -> s54 ), s2: ( (0|20) @pop2 @newM @r_M_0 @rem2 -> s54 ), s3: ( (0|20) @pop1 @newM @r_M_1 @rem1 -> s54 ), s4: ( 20 @pop1 @newstart @r_start_0 @rem1 -> s54 | 25 @shift -> s2 | 0 @shift -> s5 ), s5: ( 1 @shift -> s6 ), s6: ( 26 @shift -> s8 | 27 @shift -> s9 | 29 @shift -> s25 | 28 @shift -> s26 | 30 @shift -> s33 | 17 @shift -> s35 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s7: ( (0|20) @pop4 @newA @r_A_0 @rem4 -> s54 ), s8: ( 2 @shift -> s7 | 3 @shift -> s37 | 4 @shift -> s38 | 5 @shift -> s39 ), s9: ( (2..5|18) @pop1 @newE @r_E_3 @rem1 -> s54 | 29 @shift -> s25 | 30 @shift -> s33 | 28 @shift -> s34 | 17 @shift -> s35 | 6 @shift -> s41 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s10: ( (0|2..9|14..18) @pop3 @newN @r_N_0 @rem3 -> s54 ), s11: ( (0|2..9|14..18) @pop3 @newN @r_N_1 @rem3 -> s54 ), s12: ( (0|2..9|14..18) @pop3 @newN @r_N_2 @rem3 -> s54 ), s13: ( 11 @shift -> s14 ), s14: ( (0|2..9|14..18) @pop4 @newN @r_N_3 @rem4 -> s54 ), s15: ( 11 @shift -> s16 ), s16: ( (0|2..9|14..18) @pop4 @newN @r_N_4 @rem4 -> s54 ), s17: ( 11 @shift -> s18 ), s18: ( (0|2..9|14..18) @pop4 @newN @r_N_5 @rem4 -> s54 ), s19: ( 11 @shift -> s20 ), s20: ( (0|2..9|14..18) @pop4 @newN @r_N_6 @rem4 -> s54 ), s21: ( 11 @shift -> s22 ), s22: ( (0|2..9|14..18) @pop4 @newN @r_N_7 @rem4 -> s54 ), s23: ( 11 @shift -> s24 ), s24: ( (0|2..9|14..18) @pop4 @newN @r_N_8 @rem4 -> s54 ), s25: ( (0|2..9|14..18) @pop1 @newN @r_N_9 @rem1 -> s54 ), s26: ( (0|2..6|14..18) @pop1 @newT @r_T_2 @rem1 -> s54 | 7 @shift -> s27 | 8 @shift -> s28 | 9 @shift -> s29 ), s27: ( 0 @shift -> s10 | 10 @shift -> s13 | 5 @shift -> s15 ), s28: ( 0 @shift -> s11 | 10 @shift -> s17 | 5 @shift -> s19 ), s29: ( 0 @shift -> s12 | 10 @shift -> s21 | 5 @shift -> s23 ), s30: ( (0|2..9|14..18) @pop2 @newK @r_K_0 @rem2 -> s54 ), s31: ( (0|2..9|14..18) @pop2 @newK @r_K_1 @rem2 -> s54 ), s32: ( (0|2..9|14..18) @pop2 @newK @r_K_2 @rem2 -> s54 ), s33: ( (0|2..9|14..18) @pop1 @newK @r_K_3 @rem1 -> s54 | 12 @shift -> s30 | 13 @shift -> s31 | 10 @shift -> s32 ), s34: ( (0|2..6|14..18) @pop2 @newT @r_T_1 @rem2 -> s54 | 7 @shift -> s27 | 8 @shift -> s28 | 9 @shift -> s29 ), s35: ( 27 @shift -> s9 | 29 @shift -> s25 | 28 @shift -> s26 | 30 @shift -> s33 | 17 @shift -> s35 | 26 @shift -> s40 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s36: ( (0|2..10|12..18) @pop3 @newF @r_F_3 @rem3 -> s54 ), s37: ( 29 @shift -> s25 | 28 @shift -> s26 | 30 @shift -> s33 | 17 @shift -> s35 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 | 27 @shift -> s53 ), s38: ( 29 @shift -> s25 | 28 @shift -> s26 | 30 @shift -> s33 | 17 @shift -> s35 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 | 27 @shift -> s52 ), s39: ( 29 @shift -> s25 | 28 @shift -> s26 | 30 @shift -> s33 | 17 @shift -> s35 | 27 @shift -> s42 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s40: ( 18 @shift -> s36 | 3 @shift -> s37 | 4 @shift -> s38 | 5 @shift -> s39 ), s41: ( 29 @shift -> s25 | 30 @shift -> s33 | 17 @shift -> s35 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 | 28 @shift -> s51 ), s42: ( (2..5|18) @pop3 @newE @r_E_2 @rem3 -> s54 | 29 @shift -> s25 | 30 @shift -> s33 | 28 @shift -> s34 | 17 @shift -> s35 | 6 @shift -> s41 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s43: ( (0|2..9|14..18) @pop3 @newK @r_K_4 @rem3 -> s54 ), s44: ( (0|2..9|14..18) @pop3 @newK @r_K_5 @rem3 -> s54 ), s45: ( (0|2..9|14..18) @pop3 @newK @r_K_6 @rem3 -> s54 ), s46: ( 17 @shift -> s35 | 30 @shift -> s47 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s47: ( (0|2..9|14..18) @pop2 @newK @r_K_7 @rem2 -> s54 | 12 @shift -> s43 | 13 @shift -> s44 | 10 @shift -> s45 ), s48: ( (0|2..10|12..18) @pop1 @newF @r_F_0 @rem1 -> s54 ), s49: ( (0|2..10|12..18) @pop1 @newF @r_F_1 @rem1 -> s54 ), s50: ( (0|2..10|12..18) @pop1 @newF @r_F_2 @rem1 -> s54 ), s51: ( (0|2..6|14..18) @pop3 @newT @r_T_0 @rem3 -> s54 | 7 @shift -> s27 | 8 @shift -> s28 | 9 @shift -> s29 ), s52: ( (2..5|18) @pop3 @newE @r_E_1 @rem3 -> s54 | 29 @shift -> s25 | 30 @shift -> s33 | 28 @shift -> s34 | 17 @shift -> s35 | 6 @shift -> s41 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s53: ( (2..5|18) @pop3 @newE @r_E_0 @rem3 -> s54 | 29 @shift -> s25 | 30 @shift -> s33 | 28 @shift -> s34 | 17 @shift -> s35 | 6 @shift -> s41 | 14 @shift -> s46 | 15 @shift -> s48 | 16 @shift -> s49 | 0 @shift -> s50 ), s54: ( '' -> final ) ; }%% %% write data; Parser::Parser( ) { } int Parser::init( ) { %% write init; return 0; } int Parser::execute( LangEl *_data, int _len ) { LangEl *p = _data; LangEl *pe = _data+_len; %% write exec; if ( cs == Parser_error ) return -1; if ( cs >= Parser_first_final ) return 1; return 0; } int Parser::finish( ) { if ( cs == Parser_error ) return -1; if ( cs >= Parser_first_final ) return 1; return 0; } void Parser::parseLangEl( LangEl *lel ) { redLel = 0; execute( lel, 1 ); while ( redLel != 0 ) { execute( redLel, 1 ); redLel = 0; execute( lel, 1 ); } } int Parser::pop( int n ) { for ( int i = n-1; i >= 0; i-- ) rhs[i] = pop(); return rhs[0]->state; } void Parser::rem( LangEl *lel, int n ) { for ( int i = n-1; i >= 0; i-- ) delete rhs[i]; } int Parser::done( ) { Token *eof = new Token; eof->type = l__eof; eof->line = 0; eof->pos = 0; parseLangEl( eof ); return finish(); } #line 77 "tmp.gmr" #include #define MAX_TOKS 10000 struct TokList { TokList() : numToks(0) { } void append( int type ); int parse(); Token *toks[MAX_TOKS]; int numToks; }; void TokList::append( int type ) { assert( numToks < MAX_TOKS ); toks[numToks] = new Token; toks[numToks]->type = type; numToks += 1; } int TokList::parse() { Parser parser; parser.init(); for ( int i = 0; i < numToks; i++ ) parser.parseLangEl( toks[i] ); return parser.done(); } void test0() { TokList tokList; tokList.append( tt_id ); tokList.append( tt_equals ); tokList.append( tt_id ); tokList.append( tt_star ); tokList.append( tt_minus ); tokList.append( tt_andFSM ); tokList.append( tt_dot ); tokList.append( tt_id ); tokList.append( tt_semi ); tokList.append( tt_id ); tokList.append( tt_equals ); tokList.append( tt_id ); tokList.append( tt_andFSM ); tokList.append( tt_id ); tokList.append( tt_semi ); cout << tokList.parse() << endl; } void test1() { TokList tokList; tokList.append( tt_id ); tokList.append( tt_equals ); tokList.append( tt_open ); tokList.append( tt_orFSM ); tokList.append( tt_minus ); tokList.append( tt_andFSM ); tokList.append( tt_close ); tokList.append( tt_star ); tokList.append( tt_semi ); cout << tokList.parse() << endl; } void test2() { TokList tokList; tokList.append( tt_id ); tokList.append( tt_equals ); tokList.append( tt_not ); tokList.append( tt_open ); tokList.append( tt_orFSM ); tokList.append( tt_minus ); tokList.append( tt_not ); tokList.append( tt_andFSM ); tokList.append( tt_close ); tokList.append( tt_star ); tokList.append( tt_semi ); cout << tokList.parse() << endl; } void test3() { TokList tokList; tokList.append( tt_id ); tokList.append( tt_equals ); tokList.append( tt_id ); tokList.append( tt_colon ); tokList.append( tt_minus ); tokList.append( tt_number ); tokList.append( tt_id ); tokList.append( tt_colon ); tokList.append( tt_id ); tokList.append( tt_id ); tokList.append( tt_dollar ); tokList.append( tt_plus ); tokList.append( tt_number ); tokList.append( tt_id ); tokList.append( tt_percent ); tokList.append( tt_minus ); tokList.append( tt_number ); tokList.append( tt_semi ); cout << tokList.parse() << endl; } void test4() { TokList tokList; tokList.append( tt_id ); tokList.append( tt_equals ); tokList.append( tt_id ); tokList.append( tt_pipe ); tokList.append( tt_id ); tokList.append( tt_amp ); tokList.append( tt_id ); tokList.append( tt_minus ); tokList.append( tt_id ); tokList.append( tt_semi ); cout << tokList.parse() << endl; } int main() { test0(); test1(); test2(); test3(); test4(); } #ifdef _____OUTPUT_____ F = tt_id; K = F tt_star; N = K; T = N; E = T; F = tt_andFSM; K = F; N = K; T = N; F = tt_id; K = F; N = K; T = T tt_dot N; E = E tt_minus T; A = tt_id tt_equals E tt_semi; M = A; F = tt_id; K = F; N = K; T = N; F = tt_andFSM; K = F; N = K; T = T N; F = tt_id; K = F; N = K; T = T N; E = T; A = tt_id tt_equals E tt_semi; M = M A; start = M; 1 F = tt_orFSM; K = F; N = K; T = N; E = T; F = tt_andFSM; K = F; N = K; T = N; E = E tt_minus T; F = tt_open E tt_close; K = F tt_star; N = K; T = N; E = T; A = tt_id tt_equals E tt_semi; M = A; start = M; 1 F = tt_orFSM; K = F; N = K; T = N; E = T; F = tt_andFSM; K = tt_not F; N = K; T = N; E = E tt_minus T; F = tt_open E tt_close; K = tt_not F tt_star; N = K; T = N; E = T; A = tt_id tt_equals E tt_semi; M = A; start = M; 1 F = tt_id; K = F; N = K; N = N tt_colon tt_minus tt_number; T = N; F = tt_id; K = F; N = K; N = N tt_colon tt_id; T = T N; F = tt_id; K = F; N = K; N = N tt_dollar tt_plus tt_number; T = T N; F = tt_id; K = F; N = K; N = N tt_percent tt_minus tt_number; T = T N; E = T; A = tt_id tt_equals E tt_semi; M = A; start = M; 1 F = tt_id; K = F; N = K; T = N; E = T; F = tt_id; K = F; N = K; T = N; E = E tt_pipe T; F = tt_id; K = F; N = K; T = N; E = E tt_amp T; F = tt_id; K = F; N = K; T = N; E = E tt_minus T; A = tt_id tt_equals E tt_semi; M = A; start = M; 1 #endif ragel-6.10/test/builtin.rl0000664000175000017500000002147213065111230012437 00000000000000/* * @LANG: c */ #include void alph(const char *type) { printf("%s\n", type); } struct builtin { int cs; }; %%{ machine builtin; alphtype unsigned int; variable cs fsm->cs; main := ( any @{alph("any");} | ascii @{alph("ascii");} | extend @{alph("extend");} | alpha @{alph("alpha");} | digit @{alph("digit");} | alnum @{alph("alnum");} | lower @{alph("lower");} | upper @{alph("upper");} | cntrl @{alph("cntrl");} | graph @{alph("graph");} | print @{alph("print");} | punct @{alph("punct");} | space @{alph("space");} | xdigit @{alph("xdigit");} )*; }%% %% write data; void builtin_init( struct builtin *fsm ) { %% write init; } void builtin_execute( struct builtin *fsm, const unsigned int *data, int len ) { const unsigned int *p = data; const unsigned int *pe = data+len; %% write exec; } int builtin_finish( struct builtin *fsm ) { if ( fsm->cs == builtin_error ) return -1; else if ( fsm->cs >= builtin_first_final ) return 1; return 0; } #include #define BUFSIZE 2048 struct builtin fsm; char buf[BUFSIZE]; unsigned int i; int test( const unsigned int *data, int len ) { builtin_init( &fsm ); builtin_execute( &fsm, data, len ); if ( builtin_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); return 0; } #define DLEN 258 unsigned int data[DLEN] = { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 }; int main() { test( data, DLEN ); return 0; } #ifdef _____OUTPUT_____ any any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl space any ascii extend cntrl space any ascii extend cntrl space any ascii extend cntrl space any ascii extend cntrl space any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend cntrl any ascii extend print space any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend digit alnum graph print xdigit any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend alpha alnum upper graph print xdigit any ascii extend alpha alnum upper graph print xdigit any ascii extend alpha alnum upper graph print xdigit any ascii extend alpha alnum upper graph print xdigit any ascii extend alpha alnum upper graph print xdigit any ascii extend alpha alnum upper graph print xdigit any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend alpha alnum upper graph print any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend alpha alnum lower graph print xdigit any ascii extend alpha alnum lower graph print xdigit any ascii extend alpha alnum lower graph print xdigit any ascii extend alpha alnum lower graph print xdigit any ascii extend alpha alnum lower graph print xdigit any ascii extend alpha alnum lower graph print xdigit any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend alpha alnum lower graph print any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend graph print punct any ascii extend cntrl any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any extend any ACCEPT #endif ragel-6.10/test/java2.rl0000664000175000017500000000131613065111230011767 00000000000000/* * @LANG: java */ class java2 { %%{ machine java1; alphtype int; main := 1 2 3 4 ( 5 6 7 8 | 9 10 11 12 ) 1073741824; }%% %% write data; static void test( int data[] ) { int cs, p = 0, pe = data.length; int top; %% write init; %% write exec; if ( cs >= java1_first_final ) System.out.println( "ACCEPT" ); else System.out.println( "FAIL" ); } static final int t1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 1073741824 }; static final int t2[] = { 1, 2, 3, 4, 9, 10, 11, 12, 1073741824 }; static final int t3[] = { 1, 2, 3, 4, 1073741824 }; public static void main( String args[] ) { test( t1 ); test( t2 ); test( t3 ); } } /* _____OUTPUT_____ ACCEPT ACCEPT FAIL */ ragel-6.10/test/clang4.rl0000664000175000017500000001073013065111230012134 00000000000000/* * @LANG: indep * @NEEDS_EOF: yes */ char array[32]; int pos; int line; %% pos = 0; line = 1; %%{ machine clang; # Function to buffer a character. action bufChar { array[pos] = fc; pos = pos + 1; } # Function to clear the buffer. action clearBuf { pos = 0; } # Functions to dump tokens as they are matched. action ident { prints "ident("; printi line; prints ","; printi pos; prints "): "; printb array; prints "\n"; } action literal { prints "literal("; printi line; prints ","; printi pos; prints "): "; printb array; prints "\n"; } action float { prints "float("; printi line; prints ","; printi pos; prints "): "; printb array; prints "\n"; } action integer { prints "int("; printi line; prints ","; printi pos; prints "): "; printb array; prints "\n"; } action hex { prints "hex("; printi line; prints ","; printi pos; prints "): "; printb array; prints "\n"; } action symbol { prints "symbol("; printi line; prints ","; printi pos; prints "): "; printb array; prints "\n"; } # Alpha numberic characters or underscore. alnumu = alnum | '_'; # Alpha charactres or underscore. alphau = alpha | '_'; # Symbols. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving dump the symbol. symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; # Identifier. Upon entering clear the buffer. On all transitions # buffer a character. Upon leaving, dump the identifier. ident = (alphau . alnumu*) >clearBuf $bufChar %ident; # Match single characters inside literal strings. Or match # an escape sequence. Buffers the charater matched. sliteralChar = ( extend - ['\\] ) @bufChar | ( '\\' . extend @bufChar ); dliteralChar = ( extend - ["\\] ) @bufChar | ( '\\' . extend @bufChar ); # Single quote and double quota literals. At the start clear # the buffer. Upon leaving dump the literal. sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; literal = sliteral | dliteral; # Whitespace is standard ws, newlines and control codes. whitespace = any - 33 .. 126; # Describe both c style comments and c++ style comments. The # priority bump on tne terminator of the comments brings us # out of the extend* which matches everything. ccComment = '//' . extend* $0 . '\n' @1; cComment = '/!' . extend* $0 . '!/' @1; # Match an integer. We don't bother clearing the buf or filling it. # The float machine overlaps with int and it will do it. integer = digit+ %integer; # Match a float. Upon entering the machine clear the buf, buffer # characters on every trans and dump the float upon leaving. float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; # Match a hex. Upon entering the hex part, clear the buf, buffer characters # on every trans and dump the hex on leaving transitions. hex = '0x' . xdigit+ >clearBuf $bufChar %hex; # Or together all the lanuage elements. fin = ( ccComment | cComment | symbol | ident | literal | whitespace | integer | float | hex ); # Star the language elements. It is critical in this type of application # that we decrease the priority of out transitions before doing so. This # is so that when we see 'aa' we stay in the fin machine to match an ident # of length two and not wrap around to the front to match two idents of # length one. clang_main = ( fin $1 %0 )*; # This machine matches everything, taking note of newlines. newline = ( any | '\n' @{ line = line + 1; } )*; # The final fsm is the lexer intersected with the newline machine which # will count lines for us. Since the newline machine accepts everything, # the strings accepted is goverened by the clang_main machine, onto which # the newline machine overlays line counting. main := clang_main & newline; }%% /* _____INPUT_____ "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" _____INPUT_____ */ /* _____OUTPUT_____ int(1,3): 999 hex(1,6): aAFF99 float(1,5): 99.99 literal(2,5): lksdj literal(8,12): literal hex(8,5): 00aba ident(8,8): foobardd symbol(8,1): . ident(8,4): ddsf hex(8,1): 0 symbol(8,1): . int(8,1): 9 ACCEPT ident(1,17): wordwithnum00asdf int(2,3): 000 ident(2,14): wordfollowsnum symbol(2,1): , ident(2,5): makes ident(2,3): new ident(2,6): symbol ident(4,9): finishing ident(4,5): early FAIL _____OUTPUT_____ */ ragel-6.10/test/cond7.rl0000664000175000017500000000154613065111230012003 00000000000000/* * @LANG: indep */ int i; int c; %% %%{ machine foo; action testi {i > 0} action inc { i = i - 1; c = (fc); prints "item: "; printi c; prints "\n"; } count = [0-9] @{ i = (fc - '0'); prints "count: "; printi i; prints "\n"; }; sub = count # record the number of digits ( digit when testi @inc )* outwhen !testi; main := sub sub '\n'; }%% /* _____INPUT_____ "00\n" "019\n" "190\n" "1719\n" "1040000\n" "104000a\n" "104000\n" _____INPUT_____ */ /* _____OUTPUT_____ count: 0 count: 0 ACCEPT count: 0 count: 1 item: 57 ACCEPT count: 1 item: 57 count: 0 ACCEPT count: 1 item: 55 count: 1 item: 57 ACCEPT count: 1 item: 48 count: 4 item: 48 item: 48 item: 48 item: 48 ACCEPT count: 1 item: 48 count: 4 item: 48 item: 48 item: 48 FAIL count: 1 item: 48 count: 4 item: 48 item: 48 item: 48 FAIL _____OUTPUT_____ */ ragel-6.10/test/call1.rl0000664000175000017500000000261613065111230011764 00000000000000/* * @LANG: c */ #include #include int num = 0; struct test { int cs, top, stack[32]; }; %%{ machine test; access fsm->; action check_num { if ( num & 1 ) fcall *fentry(odd); else fcall even; } # Test call and return functionality. even := 'even' any @{fhold; fret;}; odd := 'odd' any @{fhold; fret;}; num = [0-9]+ ${ num = num * 10 + (fc - '0'); }; even_odd = num ' ' @check_num "\n"; # Test calls in out actions. fail := !(any*); out_acts = 'OA ok\n' | 'OA error1\n' | 'OA error2\n'; main := even_odd | out_acts; }%% %% write data; void test_init( struct test *fsm ) { num = 0; %% write init; } void test_execute( struct test *fsm, const char *data, int len ) { const char *p = data; const char *pe = data+len; %% write exec; } int test_finish( struct test *fsm ) { if ( fsm->cs == test_error ) return -1; if ( fsm->cs >= test_first_final ) return 1; return 0; } #define BUFSIZE 1024 void test( char *buf ) { struct test test; test_init( &test ); test_execute( &test, buf, strlen(buf) ); if ( test_finish( &test ) > 0 ) printf( "ACCEPT\n" ); else printf( "FAIL\n" ); } int main() { test( "78 even\n" ); test( "89 odd\n" ); test( "1 even\n" ); test( "0 odd\n" ); test( "OA ok\n" ); test( "OA error1\n" ); test( "OA error2\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT FAIL FAIL ACCEPT ACCEPT ACCEPT #endif ragel-6.10/test/call3.rl0000664000175000017500000000427713065111230011773 00000000000000/* * @LANG: obj-c */ #include #include #include int num = 0; @interface CallTest : Object { @public /* State machine operation data. */ int cs, top, stack[32]; }; // 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) initFsm; // 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) executeWithData:(const char *)data len:(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; @end @implementation CallTest %%{ machine CallTest; action check_num { if ( num & 1 ) fcall odd; else fcall even; } # Test call and return functionality. even := 'even' any @{fhold; fret;}; odd := 'odd' any @{fhold; fret;}; num = [0-9]+ ${ num = num * 10 + (fc - '0'); }; even_odd = num ' ' @check_num "\n"; # Test calls in out actions. fail := !(any*); out_acts = 'OA ok\n' | 'OA error1\n' | 'OA error2\n'; main := even_odd | out_acts; }%% %% write data; - (void) initFsm; { num = 0; %% write init; } - (void) executeWithData:(const char *)data len:(int)len; { const char *p = data; const char *pe = data + len; %% write exec; } - (int) finish; { if ( cs == CallTest_error ) return -1; return ( cs >= CallTest_first_final ) ? 1 : 0; } @end #define BUFSIZE 1024 void test( char *buf ) { CallTest *test = [[CallTest alloc] init]; [test initFsm]; [test executeWithData:buf len:strlen(buf)]; if ( [test finish] > 0 ) printf( "ACCEPT\n" ); else printf( "FAIL\n" ); } int main() { test( "78 even\n" ); test( "89 odd\n" ); test( "1 even\n" ); test( "0 odd\n" ); test( "OA ok\n" ); test( "OA error1\n" ); test( "OA error2\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT ACCEPT FAIL FAIL ACCEPT ACCEPT ACCEPT #endif ragel-6.10/test/cond6.rl0000664000175000017500000000153513065111230012000 00000000000000/* * @LANG: c++ */ /* Balanced parenthesis with conditions. */ #include #include using std::cout; using std::endl; %%{ machine cond; write data noerror; }%% void test( const char *str ) { int cs = cond_start, n = 0; const char *p = str; const char *pe = str + strlen( str ); %%{ comment = '(' @{n=0;} ( '('@{n++;} | ')'@{n--;} | [^()] )* :> ')' when{!n}; main := ' '* comment ' '* '\n' @{cout << "success";}; write exec; }%% if ( cs < cond_first_final ) cout << "failure"; cout << endl; } int main() { test( "( ( )\n" ); test( "()()\n" ); test( "(((\n" ); test( "((()\n" ); test( "((())\n" ); test( "()\n" ); test( "((()))\n" ); test( "(()())\n" ); test( "((())()(((()))))\n" ); return 0; } #ifdef _____OUTPUT_____ failure failure failure failure failure success success success success #endif ragel-6.10/test/cond1.rl0000664000175000017500000000170313065111230011770 00000000000000/* * @LANG: indep * @ALLOW_GENFLAGS: -T0 -T1 -G0 -G1 -G2 */ bool i; bool j; bool k; %% %%{ machine foo; action c1 {i} action c2 {j} action c3 {k} action one { prints " one\n";} action two { prints " two\n";} action three { prints " three\n";} action seti { if ( fc == 48 ) i = false; else i = true; } action setj { if ( fc == 48 ) j = false; else j = true; } action setk { if ( fc == 48 ) k = false; else k = true; } action break {fbreak;} one = 'a' 'b' when c1 'c' @one; two = 'a'* 'b' when c2 'c' @two; three = 'a'+ 'b' when c3 'c' @three; main := [01] @seti [01] @setj [01] @setk ( one | two | three ) '\n' @break; }%% /* _____INPUT_____ "000abc\n" "100abc\n" "010abc\n" "110abc\n" "001abc\n" "101abc\n" "011abc\n" "111abc\n" _____INPUT_____ */ /* _____OUTPUT_____ FAIL one ACCEPT two ACCEPT one two ACCEPT three ACCEPT one three ACCEPT two three ACCEPT one two three ACCEPT _____OUTPUT_____ */ ragel-6.10/test/cond2.rl0000664000175000017500000000202213065111230011764 00000000000000/* * @LANG: c++ */ #include #include using std::cout; using std::endl; %%{ machine foo; action c1 {i} action c2 {j} action one { cout << " one" << endl;} action two { cout << " two" << endl;} main := ( [a-z] | ('\n' when c1 @one) )* ('\n' when c2 @two); }%% %% write data noerror; void test( int i, int j, const char *str ) { int cs = foo_start; const char *p = str; const char *pe = str + strlen( str ); cout << "run:" << endl; %% write exec; if ( cs >= foo_first_final ) cout << " success" << endl; else cout << " failure" << endl; cout << endl; } int main() { test( 0, 0, "hi\n\n" ); test( 1, 0, "hi\n\n" ); test( 0, 1, "hi\n" ); test( 0, 1, "hi\n\n" ); test( 1, 1, "hi\n" ); test( 1, 1, "hi\n\n" ); test( 1, 1, "hi\n\nx" ); return 0; } #ifdef _____OUTPUT_____ run: failure run: one one failure run: two success run: two failure run: one two success run: one two one two success run: one two one two failure #endif ragel-6.10/test/patact.rl0000664000175000017500000000311613065111230012240 00000000000000/* * @LANG: indep */ char comm; int top; int stack[32]; ptr ts; ptr te; int act; int val; %% %%{ machine patact; other := |* [a-z]+ => { prints "word\n"; }; [0-9]+ => { prints "num\n"; }; [\n ] => { prints "space\n"; }; *|; exec_test := |* [a-z]+ => { prints "word (w/lbh)\n"; fexec te-1; fgoto other; }; [a-z]+ ' foil' => { prints "word (c/lbh)\n"; }; [\n ] => { prints "space\n"; }; '22' => { prints "num (w/switch)\n"; }; [0-9]+ => { prints "num (w/switch)\n"; fexec te-1; fgoto other;}; [0-9]+ ' foil' => {prints "num (c/switch)\n"; }; '!';# => { prints "immdiate\n"; fgoto exec_test; }; *|; semi := |* ';' => { prints "in semi\n"; fgoto main; }; *|; main := |* [a-z]+ => { prints "word (w/lbh)\n"; fhold; fgoto other; }; [a-z]+ ' foil' => { prints "word (c/lbh)\n"; }; [\n ] => { prints "space\n"; }; '22' => { prints "num (w/switch)\n"; }; [0-9]+ => { prints "num (w/switch)\n"; fhold; fgoto other;}; [0-9]+ ' foil' => {prints "num (c/switch)\n"; }; ';' => { prints "going to semi\n"; fhold; fgoto semi;}; '!' => { prints "immdiate\n"; fgoto exec_test; }; *|; }%% /* _____INPUT_____ "abcd foix\n" "abcd\nanother\n" "123 foix\n" "!abcd foix\n" "!abcd\nanother\n" "!123 foix\n" ";" _____INPUT_____ */ /* _____OUTPUT_____ word (w/lbh) word space word space ACCEPT word (w/lbh) word space word space ACCEPT num (w/switch) num space word space ACCEPT immdiate word (w/lbh) word space word space ACCEPT immdiate word (w/lbh) word space word space ACCEPT immdiate num (w/switch) num space word space ACCEPT going to semi in semi ACCEPT _____OUTPUT_____ */ ragel-6.10/test/forder1.rl0000664000175000017500000000223013065111230012322 00000000000000/* * @LANG: c */ #include #include struct forder { int cs; }; %%{ machine forder; variable cs fsm->cs; second = 'b' >{printf("enter b1\n");} >{printf("enter b2\n");} ; first = 'a' %{printf("leave a\n");} @{printf("finish a\n");} ; main := first . second . '\n'; }%% %% write data; void forder_init( struct forder *fsm ) { %% write init; } void forder_execute( struct forder *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int forder_finish( struct forder *fsm ) { if ( fsm->cs == forder_error ) return -1; if ( fsm->cs >= forder_first_final ) return 1; return 0; } struct forder fsm; void test( char *buf ) { int len = strlen(buf); forder_init( &fsm ); forder_execute( &fsm, buf, len ); if ( forder_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "ab\n"); test( "abx\n"); test( "" ); test( "ab\n" "fail after newline\n" ); return 0; } #ifdef _____OUTPUT_____ finish a leave a enter b1 enter b2 ACCEPT finish a leave a enter b1 enter b2 FAIL FAIL finish a leave a enter b1 enter b2 FAIL #endif ragel-6.10/test/eofact.rl0000664000175000017500000000076513065111230012234 00000000000000/* * @LANG: indep * * Test works with split code gen. */ %% %%{ machine eofact; action a1 { prints "a1\n"; } action a2 { prints "a2\n"; } action a3 { prints "a3\n"; } action a4 { prints "a4\n"; } main := ( 'hello' @eof a1 %eof a2 '\n'? | 'there' @eof a3 %eof a4 ); }%% /* _____INPUT_____ "" "h" "hell" "hello" "hello\n" "t" "ther" "there" "friend" _____INPUT_____ */ /* _____OUTPUT_____ a1 a3 FAIL a1 FAIL a1 FAIL a2 ACCEPT ACCEPT a3 FAIL a3 FAIL a4 ACCEPT FAIL _____OUTPUT_____ */ ragel-6.10/test/langtrans_c.txl0000664000175000017500000001442413065111230013455 00000000000000include "testcase.txl" define c_statements [repeat c_lang_stmt] end define define c_lang_stmt [al_ragel_stmt] | [c_variable_decl] | [c_expr_stmt] | [c_if_stmt] | [EX] '{ [IN] [NL] [c_statements] [EX] '} [IN] [NL] end define define c_variable_decl [c_type_decl] [id] [opt union] '; [NL] end define define c_type_decl [al_type_decl] | 'char '* end define define c_expr_stmt [c_expr] '; [NL] end define define c_expr [c_term] [repeat c_expr_extend] end define define c_expr_extend [al_expr_op] [c_term] end define define c_term [al_term] | [id] '( [c_args] ') end define define c_args [list c_expr] end define define c_sign '- | '+ end define define c_if_stmt 'if '( [c_expr] ') [NL] [IN] [c_lang_stmt] [EX] [opt c_else] end define define c_else 'else [NL] [IN] [c_lang_stmt] [EX] end define define c_lang [c_statements] '%% [NL] [c_statements] [ragel_def] end define define program [lang_indep] | [c_lang] end define redefine al_host_block '{ [NL] [IN] [al_statements] [EX] '} [NL] | '{ [NL] [IN] [c_statements] [EX] '} [NL] end define redefine cond_action_stmt 'action [id] '{ [al_expr] '} [NL] | 'action [id] '{ [c_expr] '} [NL] end redefine rule boolTypes replace [al_type_decl] 'bool by 'int end rule rule ptrTypes replace [c_type_decl] 'ptr by 'char '* end rule rule boolVals1 replace [al_term] 'true by '1 end rule rule boolVals2 replace [al_term] 'false by '0 end rule function alStmtToC1 AlStmt [action_lang_stmt] deconstruct AlStmt VarDecl [al_variable_decl] deconstruct VarDecl Type [al_type_decl] Id [id] OptUnion [opt union]'; construct CType [c_type_decl] Type construct Result [c_variable_decl] CType [boolTypes] [ptrTypes] Id OptUnion '; replace [repeat c_lang_stmt] by Result end function rule alTermToC1 replace [al_term] 'first_token_char by 'ts '[0] end rule rule alTermToC2 replace [al_term] '< _ [al_type_decl] '> '( AlExpr [al_expr] ') by '( AlExpr ') end rule function alTermToC replace [al_term] AlTerm [al_term] by AlTerm [alTermToC1] [alTermToC2] end function function alExprExtendToC AlExprExtend [repeat al_expr_extend] deconstruct AlExprExtend Op [al_expr_op] Term [al_term] Rest [repeat al_expr_extend] construct RestC [repeat c_expr_extend] _ [alExprExtendToC Rest] replace [repeat c_expr_extend] by Op Term [alTermToC] RestC end function function alExprToC AlExpr [al_expr] deconstruct AlExpr ALTerm [al_term] AlExprExtend [repeat al_expr_extend] construct CExprExtend [repeat c_expr_extend] _ [alExprExtendToC AlExprExtend] construct Result [opt c_expr] ALTerm [alTermToC] CExprExtend replace [opt c_expr] by Result [boolVals1] [boolVals2] end function function alStmtToC2 AlStmt [action_lang_stmt] deconstruct AlStmt AlExpr [al_expr] '; construct OptCExpr [opt c_expr] _ [alExprToC AlExpr] deconstruct OptCExpr CExpr [c_expr] replace [repeat c_lang_stmt] by CExpr '; end function function alOptElseC AlOptElse [opt al_else] deconstruct AlOptElse 'else AlSubStmt [action_lang_stmt] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct CSubStmts [repeat c_lang_stmt] _ [alToC AlSubStmts] deconstruct CSubStmts CSubStmt [c_lang_stmt] replace [opt c_else] by 'else CSubStmt end function function alStmtToC3 AlStmt [action_lang_stmt] deconstruct AlStmt 'if '( AlExpr [al_expr] ') AlSubStmt [action_lang_stmt] AlOptElse [opt al_else] construct OptCExpr [opt c_expr] _ [alExprToC AlExpr] deconstruct OptCExpr CExpr [c_expr] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct CSubStmts [repeat c_lang_stmt] _ [alToC AlSubStmts] deconstruct CSubStmts CSubStmt [c_lang_stmt] construct OptCElse [opt c_else] _ [alOptElseC AlOptElse] replace [repeat c_lang_stmt] by 'if '( CExpr ') CSubStmt OptCElse end function function alStmtToC4a AlStmt [action_lang_stmt] deconstruct AlStmt 'printi Id [id] '; replace [repeat c_lang_stmt] by 'printf '( '"%i" ', Id '); end function function alStmtToC4b AlStmt [action_lang_stmt] deconstruct AlStmt 'prints String [stringlit] '; replace [repeat c_lang_stmt] by 'fputs '( String , 'stdout '); end function function alStmtToC4c AlStmt [action_lang_stmt] deconstruct AlStmt 'printb Id [id] '; replace [repeat c_lang_stmt] by 'fwrite '( Id ', '1 ', 'pos ', 'stdout '); end function function alStmtToC4d AlStmt [action_lang_stmt] deconstruct AlStmt 'print_token '; replace [repeat c_lang_stmt] by 'fwrite '( 'ts ', '1 ', 'te '- 'ts ', 'stdout '); end function function alStmtToC5 AlStmt [action_lang_stmt] deconstruct AlStmt '{ AlSubStmts [repeat action_lang_stmt] '} construct CSubStmts [repeat c_lang_stmt] _ [alToC AlSubStmts] replace [repeat c_lang_stmt] by '{ CSubStmts '} end function function alStmtToC6 AlStmt [action_lang_stmt] deconstruct AlStmt RagelStmt [al_ragel_stmt] replace [repeat c_lang_stmt] by RagelStmt end function function alToC AlStmts [repeat action_lang_stmt] deconstruct AlStmts FirstStmt [action_lang_stmt] Rest [repeat action_lang_stmt] construct FirstC [repeat c_lang_stmt] _ [alStmtToC1 FirstStmt] [alStmtToC2 FirstStmt] [alStmtToC3 FirstStmt] [alStmtToC4a FirstStmt] [alStmtToC4b FirstStmt] [alStmtToC4c FirstStmt] [alStmtToC4d FirstStmt] [alStmtToC5 FirstStmt] [alStmtToC6 FirstStmt] construct RestC [repeat c_lang_stmt] _ [alToC Rest] replace [repeat c_lang_stmt] by FirstC [. RestC] end function rule actionTransC replace [al_host_block] '{ AlStmts [repeat action_lang_stmt] '} construct CStmts [repeat c_lang_stmt] _ [alToC AlStmts] by '{ CStmts '} end rule rule condTransC replace [cond_action_stmt] 'action Id [id] '{ AlExpr [al_expr] '} construct OptCExpr [opt c_expr] _ [alExprToC AlExpr] deconstruct OptCExpr CExpr [c_expr] by 'action Id '{ CExpr '} end rule function langTransC replace [program] Definitions [repeat action_lang_stmt] '%% Initializations [repeat action_lang_stmt] RagelDef [ragel_def] construct CDefinitions [repeat c_lang_stmt] _ [alToC Definitions] construct CInitializations [repeat c_lang_stmt] _ [alToC Initializations] by CDefinitions '%% CInitializations RagelDef [actionTransC] [condTransC] end function function main replace [program] P [program] by P [langTransC] end function ragel-6.10/test/Makefile.in0000664000175000017500000006537613065122656012530 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2002-2009 Adrian Thurston # # This file is part of Ragel. # # Ragel is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Ragel is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ragel; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ragel/config.h CONFIG_CLEAN_FILES = runtests CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/runtests.in \ $(top_srcdir)/test-driver README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ FIG2DEV = @FIG2DEV@ GDC = @GDC@ GMCS = @GMCS@ GOBIN = @GOBIN@ GOBJC = @GOBJC@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVAC = @JAVAC@ KELBT = @KELBT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PUBDATE = @PUBDATE@ RAGEL = @RAGEL@ RANLIB = @RANLIB@ RUBY = @RUBY@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TXL = @TXL@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TESTS = runtests EXTRA_DIST = \ atoi1.rl clang2.rl cond7.rl element3.rl erract8.rl forder3.rl java1.rl \ range.rl scan3.rl xml.rl atoi2.rl clang3.rl cppscan1.rl eofact.rl \ erract9.rl gotocallret1.rl java2.rl recdescent1.rl scan4.rl atoi3.rl \ clang4.rl cppscan2.rl erract1.rl export1.rl gotocallret2.rl keller1.rl \ recdescent2.rl stateact1.rl awkemu.rl cond1.rl cppscan3.rl erract2.rl \ export2.rl high1.rl lmgoto.rl recdescent3.rl statechart1.rl builtin.rl \ cond2.rl cppscan4.rl erract3.rl export3.rl high2.rl mailbox1.rl \ repetition.rl strings1.rl call1.rl cond3.rl cppscan5.rl erract4.rl \ export4.rl high3.rl mailbox2.rl rlscan.rl strings2.rl call2.rl cond4.rl \ cppscan6.rl erract5.rl fnext1.rl import1.rl mailbox3.rl ruby1.rl \ tokstart1.rl call3.rl cond5.rl element1.rl erract6.rl forder1.rl \ include1.rl minimize1.rl scan1.rl union.rl clang1.rl cond6.rl \ element2.rl erract7.rl forder2.rl include2.rl patact.rl scan2.rl \ xmlcommon.rl langtrans_c.sh langtrans_csharp.sh langtrans_d.sh \ langtrans_java.sh langtrans_ruby.sh checkeofact.txl \ langtrans_csharp.txl langtrans_c.txl langtrans_d.txl langtrans_java.txl \ langtrans_ruby.txl testcase.txl cppscan1.h eofact.h mailbox1.h strings2.h CLEANFILES = \ *.c *.cpp *.m *.d *.java *.bin *.class *.exp \ *.out *_c.rl *_d.rl *_java.rl *_ruby.rl *_csharp.rl *.cs \ *_go.rl *.go *.exe all: all-am .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign test/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): runtests: $(top_builddir)/config.status $(srcdir)/runtests.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ tags TAGS: ctags CTAGS: cscope cscopelist: # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? runtests.log: runtests @p='runtests'; \ b='runtests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-TESTS check-am clean clean-generic \ cscopelist-am ctags-am distclean distclean-generic distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am recheck tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ragel-6.10/test/README0000664000175000017500000000075713065111230011315 00000000000000 The test suite now depends on TXL. Since the trend in Ragel is towards independence of the host-language, tests are now being written in a fictional mini-language designed for the purpose of testing ragel. The host language test-cases are then generated using a TXL transformation. This allows one test case to be run against all host languages in addition to all code generation styles. TXL is not open source, but a free download is available from the homepage. http://www.txl.ca/ -Adrian ragel-6.10/test/scan1.rl0000664000175000017500000000162513065111230011774 00000000000000/* * @LANG: indep */ ptr ts; ptr te; int act; int token; %% %%{ machine scanner; # Warning: changing the patterns or the input string will affect the # coverage of the scanner action types. main := |* 'a' => { prints "on last "; if ( p+1 == te ) prints "yes"; prints "\n"; }; 'b'+ => { prints "on next "; if ( p+1 == te ) prints "yes"; prints "\n"; }; 'c1' 'dxxx'? => { prints "on lag "; if ( p+1 == te ) prints "yes"; prints "\n"; }; 'd1' => { prints "lm switch1 "; if ( p+1 == te ) prints "yes"; prints "\n"; }; 'd2' => { prints "lm switch2 "; if ( p+1 == te ) prints "yes"; prints "\n"; }; [d0-9]+ '.'; '\n'; *|; }%% /* _____INPUT_____ "abbc1d1d2\n" _____INPUT_____ */ /* _____OUTPUT_____ on last yes on next yes on lag yes lm switch1 yes lm switch2 yes ACCEPT _____OUTPUT_____ */ ragel-6.10/test/rlscan.rl0000664000175000017500000001056013065111230012247 00000000000000/* * Lexes Ragel input files. * * @LANG: c++ * * Test works with split code gen. */ #include #include #include #include using namespace std; void escapeXML( const char *data ) { while ( *data != 0 ) { switch ( *data ) { case '<': cout << "<"; break; case '>': cout << ">"; break; case '&': cout << "&"; break; default: cout << *data; break; } data += 1; } } void escapeXML( char c ) { switch ( c ) { case '<': cout << "<"; break; case '>': cout << ">"; break; case '&': cout << "&"; break; default: cout << c; break; } } void escapeXML( const char *data, int len ) { for ( const char *end = data + len; data != end; data++ ) { switch ( *data ) { case '<': cout << "<"; break; case '>': cout << ">"; break; case '&': cout << "&"; break; default: cout << *data; break; } } } inline void write( const char *data ) { cout << data; } inline void write( char c ) { cout << c; } inline void write( const char *data, int len ) { cout.write( data, len ); } %%{ machine RagelScan; word = [a-zA-Z_][a-zA-Z_0-9]*; integer = [0-9]+; hex = '0x' [0-9a-fA-F] [0-9a-fA-F]*; default = ^0; EOF = 0; # Handles comments in outside code and inline blocks. c_comment := ( default* :>> '*/' ) ${ escapeXML( fc ); } @{ fret; }; action emit { escapeXML( ts, te-ts ); } # # Inline action code # ilscan := |* "'" ( [^'\\] | /\\./ )* "'" => emit; '"' ( [^"\\] | /\\./ )* '"' => emit; '/*' { write( "/*" ); fcall c_comment; }; '//' [^\n]* '\n' => emit; '{' { write( '{' ); inline_depth += 1; }; '}' { write( '}' ); /* If dropping down to the last } then return * to ragel code. */ if ( --inline_depth == 0 ) { write( "\n" ); fgoto rlscan; } }; default => { escapeXML( *ts ); }; *|; # # Ragel Tokens # rlscan := |* '}%%' { if ( !single_line ) { write( "\n" ); fgoto main; } }; '\n' { if ( single_line ) { write( "\n" ); fgoto main; } }; # Word word { write( "" ); write( ts, te-ts ); write( "\n" ); }; # Decimal integer. integer { write( "" ); write( ts, te-ts ); write( "\n" ); }; # Hexidecimal integer. hex { write( "" ); write( ts, te-ts ); write( "\n" ); }; # Consume comments. '#' [^\n]* '\n'; # Single literal string. "'" ( [^'\\] | /\\./ )* "'" { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Double literal string. '"' ( [^"\\] | /\\./ )* '"' { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Or literal. '[' ( [^\]\\] | /\\./ )* ']' { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Regex Literal. '/' ( [^/\\] | /\\./ ) * '/' { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Open an inline block '{' { inline_depth = 1; write( "{" ); fgoto ilscan; }; punct { write( "" ); escapeXML( fc ); write( "\n" ); }; default; *|; # # Outside code. # main := |* "'" ( [^'\\] | /\\./ )* "'" => emit; '"' ( [^"\\] | /\\./ )* '"' => emit; '/*' { escapeXML( ts, te-ts ); fcall c_comment; }; '//' [^\n]* '\n' => emit; '%%{' { write( "
\n" ); single_line = false; fgoto rlscan; }; '%%' { write( "
\n" ); single_line = true; fgoto rlscan; }; default { escapeXML( *ts ); }; # EOF. EOF; *|; }%% %% write data nofinal; void test( const char *data ) { std::ios::sync_with_stdio(false); int cs, act; const char *ts, *te; int stack[1], top; bool single_line = false; int inline_depth = 0; %% write init; /* Read in a block. */ const char *p = data; const char *pe = data + strlen( data ); const char *eof = pe; %% write exec; if ( cs == RagelScan_error ) { /* Machine failed before finding a token. */ cerr << "PARSE ERROR" << endl; exit(1); } } #define BUFSIZE 2048 int main() { std::ios::sync_with_stdio(false); test("hi %%{ /'}%%'/ { /*{*/ {} } + '\\'' }%%there\n"); return 0; } #ifdef _____OUTPUT_____ hi
/'}%%'/ { /*{*/ {} } + '\''
there #endif ragel-6.10/test/gotocallret2.rl0000664000175000017500000000350613065111230013370 00000000000000/* * @LANG: indep */ char comm; int top; int stack[32]; ptr ts; ptr te; int act; int val; %% %%{ machine GotoCallRet; sp = ' '; handle := any @{ prints "handle "; fhold; if ( val == 1 ) fnext *fentry(one); if ( val == 2 ) fnext *fentry(two); if ( val == 3 ) fnext main; }; one := |* '{' => { prints "{ "; fcall *fentry(one); }; "[" => { prints "[ "; fcall *fentry(two); }; "}" sp* => { prints "} "; fret; }; [a-z]+ => { prints "word "; val = 1; fgoto *fentry(handle); }; ' ' => { prints "space "; }; *|; two := |* '{' => { prints "{ "; fcall *fentry(one); }; "[" => { prints "[ "; fcall *fentry(two); }; ']' sp* => { prints "] "; fret; }; [a-z]+ => { prints "word "; val = 2; fgoto *fentry(handle); }; ' ' => { prints "space "; }; *|; main := |* '{' => { prints "{ "; fcall one; }; "[" => { prints "[ "; fcall two; }; [a-z]+ => { prints "word "; val = 3; fgoto handle; }; [a-z] ' foil' => { prints "this is the foil";}; ' ' => { prints "space "; }; '\n'; *|; }%% /* _____INPUT_____ "{a{b[c d]d}c}\n" "[a{b[c d]d}c}\n" "[a[b]c]d{ef{g{h}i}j}l\n" "{{[]}}\n" "a b c\n" "{a b c}\n" "[a b c]\n" "{]\n" "{{}\n" "[[[[[[]]]]]]\n" "[[[[[[]]}]]]\n" _____INPUT_____ */ /* _____OUTPUT_____ { word handle { word handle [ word handle space word handle ] word handle } word handle } ACCEPT [ word handle { word handle [ word handle space word handle ] word handle } word handle FAIL [ word handle [ word handle ] word handle ] word handle { word handle { word handle { word handle } word handle } word handle } word handle ACCEPT { { [ ] } } ACCEPT word handle space word handle space word handle ACCEPT { word handle space word handle space word handle } ACCEPT [ word handle space word handle space word handle ] ACCEPT { FAIL { { } FAIL [ [ [ [ [ [ ] ] ] ] ] ] ACCEPT [ [ [ [ [ [ ] ] FAIL _____OUTPUT_____ */ ragel-6.10/test/erract9.rl0000664000175000017500000000117313065111230012336 00000000000000# # @LANG: ruby # # Test the host language scanning for ruby. # %%{ machine erract9; action on_char { print("char: ", data[p..p], "\n"); } action on_err { print("err: ", data[p..p], "\n"); } action to_state { print("to state: " , data[p..p], "\n"); } main := 'heXXX' $on_char $err(on_err) $to(to_state); }%% %% write data; def run_machine( data ) p = 0; pe = data.length cs = 0 %% write init; %% write exec; print("rest: " , data[p..p+2], "\n") end inp = [ "hello\n", ] inp.each { |str| run_machine(str) } =begin _____OUTPUT_____ char: h to state: h char: e to state: e err: l rest: llo =end _____OUTPUT_____ ragel-6.10/test/tokstart1.rl0000664000175000017500000001135013065111230012717 00000000000000/* * @LANG: c++ */ #include #include using namespace std; extern char buf[]; struct Scanner { int cs, act; char *ts, *te; // 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. int execute( 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 Scanner; action to_act { cout << "to: fc = "; if ( fc == '\'' ) cout << (int)fc; else cout << fc; cout << " ts = " << ( ts == 0 ? -1 : ts-buf ) << endl; } action from_act { cout << "from: fc = "; if ( fc == '\'' ) cout << (int)fc; else cout << fc; cout << " ts = " << ( ts == 0 ? -1 : ts-buf ) << endl; } c_comm := ( any* $0 '*/' @1 @{ fgoto main; } ) $~to_act $*from_act; cxx_comm := ( any* $0 '\n' @1 @{ fgoto main; } ) $~to_act $*from_act; main := |* # Single and double literals. ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) $~ to_act $* from_act; ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) $~ to_act $* from_act; # Identifiers ( [a-zA-Z_] [a-zA-Z0-9_]* ) $~ to_act $* from_act; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) $~ to_act $* from_act; # Integer decimal. Leading part buffered by float. ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) $~ to_act $* from_act; # Integer octal. Leading part buffered by float. ( '0' [0-9]+ [ulUL]{0,2} ) $~ to_act $* from_act; # Integer hex. Leading 0 buffered by float. ( '0x' [0-9a-fA-F]+ [ulUL]{0,2} ) $~ to_act $* from_act; # Three char compounds, first item already buffered. */ ( '...' ) $~ to_act $* from_act; # Single char symbols. ( punct - [_"'] ) $~ to_act $* from_act; # Comments and whitespace. ( '/*' ) $~ to_act $* from_act { fgoto c_comm; }; ( '//' ) $~ to_act $* from_act { fgoto cxx_comm; }; ( any - 33..126 )+ $~ to_act $* from_act; *|; }%% %% write data; void Scanner::init( ) { %% write init; } int Scanner::execute( char *data, int len ) { char *p = data; char *pe = data + len; char *eof = pe; %% write exec; return 0; } int Scanner::finish( ) { if ( cs == Scanner_error ) return -1; if ( cs >= Scanner_first_final ) return 1; return 0; } void test( ) { int len = strlen( buf ); Scanner scanner; scanner.init(); scanner.execute( buf, len ); if ( scanner.cs == Scanner_error ) { /* Machine failed before finding a token. */ cout << "PARSE ERROR" << endl; } scanner.finish(); } char buf[4096]; int main() { strcpy( buf, "a b 0.98 /*\n" "9 */'\\''//hi\n" "there\n" ); test(); return 0; } #ifdef _____OUTPUT_____ from: fc = a ts = 0 to: fc = a ts = 0 from: fc = ts = 0 to: fc = a ts = -1 from: fc = ts = 1 to: fc = ts = 1 from: fc = b ts = 1 to: fc = ts = -1 from: fc = b ts = 2 to: fc = b ts = 2 from: fc = ts = 2 to: fc = b ts = -1 from: fc = ts = 3 to: fc = ts = 3 from: fc = 0 ts = 3 to: fc = ts = -1 from: fc = 0 ts = 4 to: fc = 0 ts = 4 from: fc = . ts = 4 to: fc = . ts = 4 from: fc = 9 ts = 4 to: fc = 9 ts = 4 from: fc = 8 ts = 4 to: fc = 8 ts = 4 from: fc = ts = 4 to: fc = 8 ts = -1 from: fc = ts = 8 to: fc = ts = 8 from: fc = / ts = 8 to: fc = ts = -1 from: fc = / ts = 9 to: fc = / ts = 9 from: fc = * ts = 9 to: fc = * ts = -1 from: fc = ts = -1 to: fc = ts = -1 from: fc = 9 ts = -1 to: fc = 9 ts = -1 from: fc = ts = -1 to: fc = ts = -1 from: fc = * ts = -1 to: fc = * ts = -1 from: fc = / ts = -1 to: fc = / ts = -1 from: fc = 39 ts = 16 to: fc = 39 ts = 16 from: fc = \ ts = 16 to: fc = \ ts = 16 from: fc = 39 ts = 16 to: fc = 39 ts = 16 from: fc = 39 ts = 16 to: fc = 39 ts = -1 from: fc = / ts = 20 to: fc = / ts = 20 from: fc = / ts = 20 to: fc = / ts = -1 from: fc = h ts = -1 to: fc = h ts = -1 from: fc = i ts = -1 to: fc = i ts = -1 from: fc = ts = -1 to: fc = ts = -1 from: fc = t ts = 25 to: fc = t ts = 25 from: fc = h ts = 25 to: fc = h ts = 25 from: fc = e ts = 25 to: fc = e ts = 25 from: fc = r ts = 25 to: fc = r ts = 25 from: fc = e ts = 25 to: fc = e ts = 25 from: fc = ts = 25 to: fc = e ts = -1 from: fc = ts = 30 to: fc = ts = 30 to: fc = ts = -1 #endif ragel-6.10/test/ruby1.rl0000664000175000017500000000105013065111230012021 00000000000000# # @LANG: ruby # # Test the host language scanning for ruby. # # %%{ a = 1 b = /%%\{\}/; %%{ machine ruby1; main := lower+ digit+ '\n' @{ # } c = 1 d = /\}/ puts "NL" }; }%% # %%{ e = 1 f = /%%\{\}/; %% write data; # %%{ g = 1 h = /%%\{\}/; def run_machine( data ) p = 0; pe = data.length cs = 0 %% write init; %% write exec; if cs >= ruby1_first_final puts "ACCEPT" else puts "FAIL" end end inp = [ "abc1231\n", ] inp.each { |str| run_machine(str) } =begin _____OUTPUT_____ NL ACCEPT =end _____OUTPUT_____ ragel-6.10/test/langtrans_csharp.sh0000775000175000017500000000354413065111230014322 00000000000000#!/bin/bash # file=$1 [ -f $file ] || exit 1 root=${file%.rl} class=${root}_csharp # Make a temporary version of the test case using the Java language translations. sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_csharp.txl - $class > $file.pr # Begin writing out the test case. cat << EOF /* * @LANG: csharp * @GENERATED: yes EOF grep '@ALLOW_GENFLAGS:' $file | sed 's/-G2//g' grep '@ALLOW_MINFLAGS:' $file cat << EOF */ using System; // Disables lots of warnings that appear in the test suite #pragma warning disable 0168, 0169, 0219, 0162, 0414 namespace Test { class $class { EOF # Write the data declarations sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr # Write out the machine specification. sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr # Write out the init and execute routines. cat << EOF int cs; %% write data; void init() { EOF sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr cat << EOF %% write init; } void exec( char[] data, int len ) { int p = 0; int pe = len; int eof = len; string _s; %% write exec; } void finish( ) { if ( cs >= ${class}_first_final ) Console.WriteLine( "ACCEPT" ); else Console.WriteLine( "FAIL" ); } EOF # Write out the test data. sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' BEGIN { print " static readonly string[] inp = {" } { print " " $0 "," } END { print " };" print "" print " static readonly int inplen = " NR ";" }' # Write out the main routine. cat << EOF public static void Main (string[] args) { $class machine = new $class(); for ( int i = 0; i < inplen; i++ ) { machine.init(); machine.exec( inp[i].ToCharArray(), inp[i].Length ); machine.finish(); } } } } EOF # Write out the expected output. sed -n '/\/\* _____OUTPUT_____/,/_____OUTPUT_____ \*\//p;' $file # Don't need this language-specific file anymore. rm $file.pr ragel-6.10/test/lmgoto.rl0000664000175000017500000001000013065111230012253 00000000000000/* * @LANG: c++ */ #include #include using namespace std; #define TK_Dlit 192 #define TK_Slit 193 #define TK_Float 194 #define TK_Id 195 #define TK_NameSep 197 #define TK_Arrow 211 #define TK_PlusPlus 212 #define TK_MinusMinus 213 #define TK_ArrowStar 214 #define TK_DotStar 215 #define TK_ShiftLeft 216 #define TK_ShiftRight 217 #define TK_IntegerDecimal 218 #define TK_IntegerOctal 219 #define TK_IntegerHex 220 #define TK_EqualsEquals 223 #define TK_NotEquals 224 #define TK_AndAnd 225 #define TK_OrOr 226 #define TK_MultAssign 227 #define TK_DivAssign 228 #define TK_PercentAssign 229 #define TK_PlusAssign 230 #define TK_MinusAssign 231 #define TK_AmpAssign 232 #define TK_CaretAssign 233 #define TK_BarAssign 234 #define TK_DotDotDot 240 #define TK_Whitespace 241 #define TK_Comment 242 struct Scanner { int cs, act; const char *ts, *te; bool isCxx; void token( int tok ); void run( const char *buf ); }; %%{ machine Scanner; # Process all comments, relies on isCxx being set. comment := |* '*/' { if ( ! isCxx ) fgoto main; else { cout << "comm char: " << ts[0] << endl; cout << "comm char: " << ts[1] << endl; } }; '\n' { if ( isCxx ) fgoto main; else cout << "comm char: " << ts[0] << endl; }; any { cout << "comm char: " << ts[0] << endl; }; *|; main := |* # Single and double literals. ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) { token( TK_Slit );}; ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) { token( TK_Dlit );}; # Identifiers ( [a-zA-Z_] [a-zA-Z0-9_]* ) { token( TK_Id ); }; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) { token( TK_Float );}; # Integer decimal. Leading part buffered by float. ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) { token( TK_IntegerDecimal );}; # Integer octal. Leading part buffered by float. ( '0' [0-9]+ [ulUL]{0,2} ) { token( TK_IntegerOctal );}; # Integer hex. Leading 0 buffered by float. ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) { token( TK_IntegerHex );}; # Only buffer the second item, first buffered by symbol. */ '::' {token( TK_NameSep );}; '==' {token( TK_EqualsEquals );}; '!=' {token( TK_NotEquals );}; '&&' {token( TK_AndAnd );}; '||' {token( TK_OrOr );}; '*=' {token( TK_MultAssign );}; '/=' {token( TK_DivAssign );}; '%=' {token( TK_PercentAssign );}; '+=' {token( TK_PlusAssign );}; '-=' {token( TK_MinusAssign );}; '&=' {token( TK_AmpAssign );}; '^=' {token( TK_CaretAssign );}; '|=' {token( TK_BarAssign );}; '++' {token( TK_PlusPlus );}; '--' {token( TK_MinusMinus );}; '->' {token( TK_Arrow );}; '->*' {token( TK_ArrowStar );}; '.*' {token( TK_DotStar );}; # Three char compounds, first item already buffered. */ '...' { token( TK_DotDotDot );}; # Single char symbols. ( punct - [_"'] ) { token( ts[0] );}; # Comments and whitespace. Handle these outside of the machine so that se # don't end up buffering the comments. '/*' { isCxx = false; fgoto comment; }; '//' { isCxx = true; fgoto comment; }; ( any - 33..126 )+ { token( TK_Whitespace );}; *|; }%% %% write data nofinal; void Scanner::token( int tok ) { const char *data = ts; int len = te - ts; cout << "<" << tok << "> "; if ( data != 0 ) { for ( int i = 0; i < len; i++ ) cout << data[i]; } cout << '\n'; } void Scanner::run( const char *buf ) { int len = strlen( buf ); %% write init; const char *p = buf; const char *pe = buf + len; const char *eof = pe; %% write exec; if ( cs == Scanner_error ) { /* Machine failed before finding a token. */ cout << "PARSE ERROR" << endl; } } int main() { Scanner scanner; scanner.run( "//hello*/\n" "/*hi there*/ hello 0x88" ); return 0; } #ifdef _____OUTPUT_____ comm char: h comm char: e comm char: l comm char: l comm char: o comm char: * comm char: / comm char: h comm char: i comm char: comm char: t comm char: h comm char: e comm char: r comm char: e <241> <195> hello <241> <220> 0x88 #endif ragel-6.10/test/gotocallret1.rl0000664000175000017500000000444313065111230013370 00000000000000/* * @LANG: indep */ /* * Demonstrate the use of goto, call and return. This machine expects either a * lower case char or a digit as a command then a space followed by the command * arg. If the command is a char, then the arg must be an a string of chars. * If the command is a digit, then the arg must be a string of digits. This * choice is determined by action code, rather than though transition * desitinations. */ char comm; int top; int stack[32]; %% %%{ machine GotoCallRet; # A reference to a state in an unused action caused a segfault in 5.8. */ action unusedAction { fentry(garble_line); } action err_garbling_line { prints "error: garbling line\n"; } action goto_main { fgoto main; } action recovery_failed { prints "error: failed to recover\n"; } # Error machine, consumes to end of # line, then starts the main line over. garble_line := ( (any-'\n')*'\n') >err_garbling_line @goto_main $/recovery_failed; action hold_and_return {fhold; fret;} # Look for a string of alphas or of digits, # on anything else, hold the character and return. alp_comm := alpha+ $!hold_and_return; dig_comm := digit+ $!hold_and_return; # Choose which to machine to call into based on the command. action comm_arg { if ( comm >= 'a' ) fcall alp_comm; else fcall dig_comm; } # Specifies command string. Note that the arg is left out. command = ( [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n' ) @{prints "correct command\n";}; # Any number of commands. If there is an # error anywhere, garble the line. main := command* $!{fhold;fgoto garble_line;}; }%% /* _____INPUT_____ "lkajsdf\n" "2134\n" "(\n" "\n" "*234234()0909 092 -234aslkf09`1 11\n" "1\n" "909\n" "1 a\n" "11 1\n" "a 1\n" "aa a\n" "1 1\n" "1 123456\n" "a a\n" "a abcdef\n" "h" "a aa1" _____INPUT_____ */ /* _____OUTPUT_____ error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT error: garbling line ACCEPT correct command ACCEPT correct command ACCEPT correct command ACCEPT correct command ACCEPT error: failed to recover FAIL error: garbling line error: failed to recover FAIL _____OUTPUT_____ */ ragel-6.10/test/Makefile.am0000664000175000017500000000417413065111230012466 00000000000000# # Copyright 2002-2009 Adrian Thurston # # This file is part of Ragel. # # Ragel is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Ragel is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ragel; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA TESTS = runtests EXTRA_DIST = \ atoi1.rl clang2.rl cond7.rl element3.rl erract8.rl forder3.rl java1.rl \ range.rl scan3.rl xml.rl atoi2.rl clang3.rl cppscan1.rl eofact.rl \ erract9.rl gotocallret1.rl java2.rl recdescent1.rl scan4.rl atoi3.rl \ clang4.rl cppscan2.rl erract1.rl export1.rl gotocallret2.rl keller1.rl \ recdescent2.rl stateact1.rl awkemu.rl cond1.rl cppscan3.rl erract2.rl \ export2.rl high1.rl lmgoto.rl recdescent3.rl statechart1.rl builtin.rl \ cond2.rl cppscan4.rl erract3.rl export3.rl high2.rl mailbox1.rl \ repetition.rl strings1.rl call1.rl cond3.rl cppscan5.rl erract4.rl \ export4.rl high3.rl mailbox2.rl rlscan.rl strings2.rl call2.rl cond4.rl \ cppscan6.rl erract5.rl fnext1.rl import1.rl mailbox3.rl ruby1.rl \ tokstart1.rl call3.rl cond5.rl element1.rl erract6.rl forder1.rl \ include1.rl minimize1.rl scan1.rl union.rl clang1.rl cond6.rl \ element2.rl erract7.rl forder2.rl include2.rl patact.rl scan2.rl \ xmlcommon.rl langtrans_c.sh langtrans_csharp.sh langtrans_d.sh \ langtrans_java.sh langtrans_ruby.sh checkeofact.txl \ langtrans_csharp.txl langtrans_c.txl langtrans_d.txl langtrans_java.txl \ langtrans_ruby.txl testcase.txl cppscan1.h eofact.h mailbox1.h strings2.h CLEANFILES = \ *.c *.cpp *.m *.d *.java *.bin *.class *.exp \ *.out *_c.rl *_d.rl *_java.rl *_ruby.rl *_csharp.rl *.cs \ *_go.rl *.go *.exe ragel-6.10/test/langtrans_d.txl0000664000175000017500000001336213065111230013456 00000000000000include "testcase.txl" define d_statements [repeat d_lang_stmt] end define define d_lang_stmt [al_ragel_stmt] | [d_variable_decl] | [d_expr_stmt] | [d_if_stmt] | [EX] '{ [IN] [NL] [d_statements] [EX] '} [IN] [NL] end define define d_variable_decl [d_type_decl] [id] [opt union] '; [NL] end define define d_type_decl [al_type_decl] | 'char '* end define define d_expr_stmt [d_expr] '; [NL] end define define d_expr [d_term] [repeat d_expr_extend] end define define d_expr_extend [al_expr_op] [d_term] end define define d_term [al_term] | [id] '( [d_args] ') end define define d_args [list d_expr] end define define d_sign '- | '+ end define define d_if_stmt 'if '( [d_expr] ') [NL] [IN] [d_lang_stmt] [EX] [opt d_else] end define define d_else 'else [NL] [IN] [d_lang_stmt] [EX] end define define d_lang [d_statements] '%% [NL] [d_statements] [ragel_def] end define define program [lang_indep] | [d_lang] end define redefine al_host_block '{ [NL] [IN] [al_statements] [EX] '} [NL] | '{ [NL] [IN] [d_statements] [EX] '} [NL] end define rule ptrTypes replace [d_type_decl] 'ptr by 'char '* end rule function alStmtToD1 AlStmt [action_lang_stmt] deconstruct AlStmt VarDecl [al_variable_decl] deconstruct VarDecl Type [al_type_decl] Id [id] OptUnion [opt union] '; construct DType [d_type_decl] Type construct Result [d_variable_decl] DType [ptrTypes] Id OptUnion '; replace [repeat d_lang_stmt] by Result end function rule alTermToD1 replace [al_term] 'first_token_char by 'ts '[0] end rule rule alTermToD2 replace [al_term] '< _ [al_type_decl] '> '( AlExpr [al_expr] ') by '( AlExpr ') end rule function alTermToD replace [al_term] AlTerm [al_term] by AlTerm [alTermToD1] [alTermToD2] end function function alExprExtendToD AlExprExtend [repeat al_expr_extend] deconstruct AlExprExtend Op [al_expr_op] Term [al_term] Rest [repeat al_expr_extend] construct DRest [repeat d_expr_extend] _ [alExprExtendToD Rest] replace [repeat d_expr_extend] by Op Term [alTermToD] DRest end function function alExprToD AlExpr [al_expr] deconstruct AlExpr ALTerm [al_term] AlExprExtend [repeat al_expr_extend] construct DExprExtend [repeat d_expr_extend] _ [alExprExtendToD AlExprExtend] construct Result [opt d_expr] ALTerm [alTermToD] DExprExtend replace [opt d_expr] by Result end function function alStmtToD2 AlStmt [action_lang_stmt] deconstruct AlStmt AlExpr [al_expr] '; construct OptDExpr [opt d_expr] _ [alExprToD AlExpr] deconstruct OptDExpr DExpr [d_expr] replace [repeat d_lang_stmt] by DExpr '; end function function alOptElseD AlOptElse [opt al_else] deconstruct AlOptElse 'else AlSubStmt [action_lang_stmt] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct DSubStmts [repeat d_lang_stmt] _ [alToD AlSubStmts] deconstruct DSubStmts DSubStmt [d_lang_stmt] replace [opt d_else] by 'else DSubStmt end function function alStmtToD3 AlStmt [action_lang_stmt] deconstruct AlStmt 'if '( AlExpr [al_expr] ') AlSubStmt [action_lang_stmt] AlOptElse [opt al_else] construct OptDExpr [opt d_expr] _ [alExprToD AlExpr] deconstruct OptDExpr DExpr [d_expr] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct DSubStmts [repeat d_lang_stmt] _ [alToD AlSubStmts] deconstruct DSubStmts DSubStmt [d_lang_stmt] construct OptDElse [opt d_else] _ [alOptElseD AlOptElse] replace [repeat d_lang_stmt] by 'if '( DExpr ') DSubStmt OptDElse end function function alStmtToD4a AlStmt [action_lang_stmt] deconstruct AlStmt 'printi Id [id] '; replace [repeat d_lang_stmt] by 'writef '( '"%d" ', Id ') '; end function function alStmtToD4b AlStmt [action_lang_stmt] deconstruct AlStmt 'prints String [stringlit] '; replace [repeat d_lang_stmt] by 'writef '( '"%s" ', String ') '; end function function alStmtToD4c AlStmt [action_lang_stmt] deconstruct AlStmt 'printb Id [id] '; replace [repeat d_lang_stmt] by '_s '= Id '[0..pos] '; 'writef '( '"%s" ', '_s ') '; end function function alStmtToD4d AlStmt [action_lang_stmt] deconstruct AlStmt 'print_token '; replace [repeat d_lang_stmt] by '_s '= ts '[0..(te-ts)] '; 'writef '( '"%s" ', '_s ') '; end function function alStmtToD5 AlStmt [action_lang_stmt] deconstruct AlStmt '{ AlSubStmts [repeat action_lang_stmt] '} construct DSubStmts [repeat d_lang_stmt] _ [alToD AlSubStmts] replace [repeat d_lang_stmt] by '{ DSubStmts '} end function function alStmtToD6 AlStmt [action_lang_stmt] deconstruct AlStmt RagelStmt [al_ragel_stmt] replace [repeat d_lang_stmt] by RagelStmt end function function alToD AlStmts [repeat action_lang_stmt] deconstruct AlStmts FirstStmt [action_lang_stmt] Rest [repeat action_lang_stmt] construct DFirst [repeat d_lang_stmt] _ [alStmtToD1 FirstStmt] [alStmtToD2 FirstStmt] [alStmtToD3 FirstStmt] [alStmtToD4a FirstStmt] [alStmtToD4b FirstStmt] [alStmtToD4c FirstStmt] [alStmtToD4d FirstStmt] [alStmtToD5 FirstStmt] [alStmtToD6 FirstStmt] construct DRest [repeat d_lang_stmt] _ [alToD Rest] replace [repeat d_lang_stmt] by DFirst [. DRest] end function rule actionTransD replace [al_host_block] '{ AlStmts [repeat action_lang_stmt] '} construct DStmts [repeat d_lang_stmt] _ [alToD AlStmts] by '{ DStmts '} end rule function langTransD replace [program] Definitions [repeat action_lang_stmt] '%% Initializations [repeat action_lang_stmt] RagelDef [ragel_def] construct DDefinitions [repeat d_lang_stmt] _ [alToD Definitions] construct DInitializations [repeat d_lang_stmt] _ [alToD Initializations] by DDefinitions '%% DInitializations RagelDef [actionTransD] end function function main replace [program] P [program] by P [langTransD] end function ragel-6.10/test/statechart1.rl0000664000175000017500000000254713065111230013216 00000000000000/* * @LANG: c */ /* * Test in and out state actions. */ #include #include struct state_chart { int cs; }; %%{ machine state_chart; variable cs fsm->cs; action a { printf("a"); } action b { printf("b"); } action hexa { printf("a"); } action hexb { printf("b"); } hex_a = '0x' '0'* '61' @hexa; hex_b = '0x' '0'* '62' @hexb; a = 'a' @a | hex_a; b = 'b' @b | hex_b; ws = ' '+; mach = start: ( a -> st1 | b -> st2 | zlen -> final ), st1: ( a -> st1 | ws -> start | zlen -> final ), st2: ( b -> st2 | ws -> start | zlen -> final ); main := ( mach '\n' )*; }%% %% write data; void state_chart_init( struct state_chart *fsm ) { %% write init; } void state_chart_execute( struct state_chart *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int state_chart_finish( struct state_chart *fsm ) { if ( fsm->cs == state_chart_error ) return -1; if ( fsm->cs >= state_chart_first_final ) return 1; return 0; } struct state_chart sc; void test( char *buf ) { int len = strlen( buf ); state_chart_init( &sc ); state_chart_execute( &sc, buf, len ); state_chart_finish( &sc ); printf("\n"); } int main() { test( "aa0x0061aa b\n" "bbb0x62b 0x61 0x000062\n" ); return 0; } #ifdef _____OUTPUT_____ aaaaabbbbbbab #endif ragel-6.10/test/cppscan1.h0000664000175000017500000000503313065111230012306 00000000000000#ifndef _CPPSCAN1_H #define _CPPSCAN1_H #include #include #include using namespace std; #define BUFSIZE 2048 #define TK_Dlit 192 #define TK_Slit 193 #define TK_Float 194 #define TK_Id 195 #define TK_NameSep 197 #define TK_Arrow 211 #define TK_PlusPlus 212 #define TK_MinusMinus 213 #define TK_ArrowStar 214 #define TK_DotStar 215 #define TK_ShiftLeft 216 #define TK_ShiftRight 217 #define TK_IntegerDecimal 218 #define TK_IntegerOctal 219 #define TK_IntegerHex 220 #define TK_EqualsEquals 223 #define TK_NotEquals 224 #define TK_AndAnd 225 #define TK_OrOr 226 #define TK_MultAssign 227 #define TK_DivAssign 228 #define TK_PercentAssign 229 #define TK_PlusAssign 230 #define TK_MinusAssign 231 #define TK_AmpAssign 232 #define TK_CaretAssign 233 #define TK_BarAssign 234 #define TK_DotDotDot 240 /* A growable buffer for collecting headers. */ struct Buffer { Buffer() : data(0), allocated(0), length(0) { } Buffer( const Buffer &other ) { data = (char*)malloc( other.allocated ); memcpy( data, other.data, other.length ); allocated = other.allocated; length = other.length; } ~Buffer() { empty(); } void append( char p ) { if ( ++length > allocated ) upAllocate( length*2 ); data[length-1] = p; } void append( char *str, int len ) { if ( (length += len) > allocated ) upAllocate( length*2 ); memcpy( data+length-len, str, len ); } void clear() { length = 0; } void upAllocate( int len ); void empty(); char *data; int allocated; int length; }; struct Scanner { Scanner( std::ostream &out ) : out(out) { } std::ostream &out; int line, col; int tokStart; int inlineDepth; int count; Buffer tokBuf; Buffer nonTokBuf; void pass(char c) { nonTokBuf.append(c); } void buf(char c) { tokBuf.append(c); } void token( int id ); int cs, stack, top; // 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. int 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( ); }; #endif ragel-6.10/test/langtrans_ruby.txl0000664000175000017500000002011213065111230014203 00000000000000include "testcase.txl" keys 'boolean 'new end keys define ruby_statements [repeat ruby_lang_stmt] end define define ruby_lang_stmt [al_ragel_stmt] | [ruby_expr_stmt] | [ruby_if_stmt] | [EX] 'do [IN] [NL] [ruby_statements] [EX] 'end [IN] [NL] end define define ruby_type_decl [al_type_decl] | 'boolean end define define ruby_expr_stmt [ruby_expr] '; [NL] end define define ruby_expr [ruby_term] [repeat ruby_expr_extend] end define define ruby_expr_extend [al_expr_op] [ruby_term] end define define ruby_term [al_term] | [stringlit] [union] | [id] [repeat ruby_dot_id] | [SPOFF] [id] [repeat ruby_dot_id] '( [SPON] [ruby_args] ') | [union] end define define ruby_dot_id '. [id] end define define ruby_args [list ruby_expr] end define define ruby_sign '- | '+ end define define ruby_if_stmt 'if [ruby_expr] [NL] [IN] [ruby_statements] [EX] [opt ruby_else] 'end [NL] end define define ruby_else 'else [NL] [IN] [ruby_statements] [EX] end define define ruby_lang [ruby_statements] '%% [NL] [ruby_statements] [ragel_def] end define define program [lang_indep] | [ruby_lang] end define redefine al_host_block '{ [NL] [IN] [al_statements] [EX] '} [NL] | '{ [NL] [IN] [ruby_statements] [EX] '} [NL] end define redefine cond_action_stmt 'action [id] '{ [al_expr] '} [NL] | 'action [id] '{ [ruby_expr] '} [NL] end redefine function initDecl1 VarDecl [al_variable_decl] deconstruct VarDecl 'bool Id [id] '; replace [repeat ruby_lang_stmt] by Id '= 'false '; end function function initDecl2 VarDecl [al_variable_decl] deconstruct VarDecl 'char Id [id] '; replace [repeat ruby_lang_stmt] by Id '= ''c' '; end function function initDecl3 VarDecl [al_variable_decl] deconstruct VarDecl 'int Id [id] '; replace [repeat ruby_lang_stmt] by Id '= '0 '; end function function initDecl4 VarDecl [al_variable_decl] deconstruct VarDecl 'ptr Id [id] '; replace [repeat ruby_lang_stmt] by Id '= '-1 '; end function function initDecl5 VarDecl [al_variable_decl] deconstruct VarDecl Type [al_type_decl] Id [id] Union [union] '; replace [repeat ruby_lang_stmt] by Id '= '[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] '; end function function alStmtToRuby1 AlStmt [action_lang_stmt] deconstruct AlStmt VarDecl [al_variable_decl] deconstruct VarDecl Type [al_type_decl] Id [id] OptUnion [opt union] '; replace [repeat ruby_lang_stmt] by _ [initDecl1 VarDecl] [initDecl2 VarDecl] [initDecl3 VarDecl] [initDecl4 VarDecl] [initDecl5 VarDecl] end function rule alTermToRuby1 replace [al_term] 'first_token_char by 'data '[ts] end rule rule alTermToRuby2 replace [al_term] '< _ [al_type_decl] '> '( AlExpr [al_expr] ') by '( AlExpr ') end rule function alTermToRuby replace [al_term] AlTerm [al_term] by AlTerm [alTermToRuby1] [alTermToRuby2] end function function alExprExtendToRuby AlExprExtend [repeat al_expr_extend] deconstruct AlExprExtend Op [al_expr_op] Term [al_term] Rest [repeat al_expr_extend] construct RubyRest [repeat ruby_expr_extend] _ [alExprExtendToRuby Rest] replace [repeat ruby_expr_extend] by Op Term [alTermToRuby] RubyRest end function % Note: this doesn't go into the ( al_expr ) form of al_term. function alExprToRuby AlExpr [al_expr] deconstruct AlExpr ALTerm [al_term] AlExprExtend [repeat al_expr_extend] construct RubyExprExtend [repeat ruby_expr_extend] _ [alExprExtendToRuby AlExprExtend] construct Result [opt ruby_expr] ALTerm [alTermToRuby] RubyExprExtend replace [opt ruby_expr] by Result end function function alStmtToRuby2 AlStmt [action_lang_stmt] deconstruct AlStmt AlExpr [al_expr] '; construct OptRubyExpr [opt ruby_expr] _ [alExprToRuby AlExpr] deconstruct OptRubyExpr RubyExpr [ruby_expr] replace [repeat ruby_lang_stmt] by RubyExpr '; end function function liftBlock replace [repeat ruby_lang_stmt] 'do Block [repeat ruby_lang_stmt] 'end by Block end function function alOptElseRuby AlOptElse [opt al_else] deconstruct AlOptElse 'else AlSubStmt [action_lang_stmt] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct RubySubStmts [repeat ruby_lang_stmt] _ [alToRuby AlSubStmts] deconstruct RubySubStmts RubySubStmt [ruby_lang_stmt] replace [opt ruby_else] by 'else RubySubStmts [liftBlock] end function function alStmtToRuby3 AlStmt [action_lang_stmt] deconstruct AlStmt 'if '( AlExpr [al_expr] ') AlSubStmt [action_lang_stmt] AlOptElse [opt al_else] construct OptRubyExpr [opt ruby_expr] _ [alExprToRuby AlExpr] deconstruct OptRubyExpr RubyExpr [ruby_expr] construct AlSubStmts [repeat action_lang_stmt] AlSubStmt construct RubySubStmts [repeat ruby_lang_stmt] _ [alToRuby AlSubStmts] construct OptRubyElse [opt ruby_else] _ [alOptElseRuby AlOptElse] replace [repeat ruby_lang_stmt] by 'if RubyExpr RubySubStmts [liftBlock] OptRubyElse 'end end function function alStmtToRuby4a AlStmt [action_lang_stmt] deconstruct AlStmt 'printi Id [id] '; replace [repeat ruby_lang_stmt] by 'print '( Id ') '; end function function alStmtToRuby4b AlStmt [action_lang_stmt] deconstruct AlStmt 'prints String [stringlit] '; replace [repeat ruby_lang_stmt] by 'print '( String ') '; end function function alStmtToRuby4c AlStmt [action_lang_stmt] deconstruct AlStmt 'printb Id [id] '; replace [repeat ruby_lang_stmt] by '_a = Id '[0..pos-1] '; 'print '( '_a '. 'pack '( '"c*" ') ') '; end function function alStmtToRuby4d AlStmt [action_lang_stmt] deconstruct AlStmt 'print_token '; replace [repeat ruby_lang_stmt] by '_m = 'data '[ts..te-1] '; 'print '( '_m '. 'pack '( '"c*" ') ') '; end function function alStmtToRuby5 AlStmt [action_lang_stmt] deconstruct AlStmt '{ AlSubStmts [repeat action_lang_stmt] '} construct RubySubStmts [repeat ruby_lang_stmt] _ [alToRuby AlSubStmts] replace [repeat ruby_lang_stmt] by 'do RubySubStmts 'end end function function alStmtToRuby6 AlStmt [action_lang_stmt] deconstruct AlStmt RagelStmt [al_ragel_stmt] replace [repeat ruby_lang_stmt] by RagelStmt end function rule fixCharLit replace $ [al_term] CharLit [charlit] construct BaseId [id] 'id construct Id [id] BaseId [unquote CharLit] construct EmptyString [stringlit] '"" construct Repl [stringlit] EmptyString [quote Id] by Repl '[0] end rule function alToRuby AlStmts [repeat action_lang_stmt] deconstruct AlStmts FirstStmt [action_lang_stmt] Rest [repeat action_lang_stmt] construct RubyFirst [repeat ruby_lang_stmt] _ [alStmtToRuby1 FirstStmt] [alStmtToRuby2 FirstStmt] [alStmtToRuby3 FirstStmt] [alStmtToRuby4a FirstStmt] [alStmtToRuby4b FirstStmt] [alStmtToRuby4c FirstStmt] [alStmtToRuby4d FirstStmt] [alStmtToRuby5 FirstStmt] [alStmtToRuby6 FirstStmt] [fixCharLit] construct RubyRest [repeat ruby_lang_stmt] _ [alToRuby Rest] replace [repeat ruby_lang_stmt] by RubyFirst [. RubyRest] end function rule actionTransRuby replace [al_host_block] '{ AlStmts [repeat action_lang_stmt] '} construct RubyStmts [repeat ruby_lang_stmt] _ [alToRuby AlStmts] by '{ RubyStmts '} end rule rule condTransRuby replace [cond_action_stmt] 'action Id [id] '{ AlExpr [al_expr] '} construct OptRubyExpr [opt ruby_expr] _ [alExprToRuby AlExpr] deconstruct OptRubyExpr RubyExpr [ruby_expr] by 'action Id '{ RubyExpr '} end rule rule lowercaseMachine replace $ [machine_stmt] 'machine Id [id] '; by 'machine Id [tolower] '; end rule function langTransRuby replace [program] Definitions [repeat action_lang_stmt] '%% Initializations [repeat action_lang_stmt] RagelDef [ragel_def] construct RubyDefinitions [repeat ruby_lang_stmt] _ [alToRuby Definitions] construct RubyInitializations [repeat ruby_lang_stmt] _ [alToRuby Initializations] construct NewRagelDef [ragel_def] RagelDef [actionTransRuby] [condTransRuby] [lowercaseMachine] import ArrayInits [ruby_statements] ArrayInitStmts [repeat ruby_lang_stmt] by RubyDefinitions '%% ArrayInitStmts [. RubyInitializations] NewRagelDef end function function main replace [program] P [program] export ArrayInits [ruby_statements] _ by P [langTransRuby] end function ragel-6.10/test/element1.rl0000664000175000017500000000335513065111230012503 00000000000000/* * @LANG: c++ */ #include using namespace std; struct LangEl { int key; const char *name; }; struct Fsm { 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. int 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. int execute( LangEl *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 Fsm; alphtype int; getkey fpc->key; variable eof eof_marker; action a1 {} action a2 {} action a3 {} main := ( 1 2* 3 ) ${cout << fpc->name << endl;} %/{cout << "accept" << endl;}; }%% %% write data; int Fsm::init( ) { %% write init; return 0; } int Fsm::execute( LangEl *data, int len ) { LangEl *p = data; LangEl *pe = data + len; LangEl *eof_marker = pe; %% write exec; if ( cs == Fsm_error ) return -1; if ( cs >= Fsm_first_final ) return 1; return 0; } int Fsm::finish( ) { if ( cs == Fsm_error ) return -1; if ( cs >= Fsm_first_final ) return 1; return 0; } int main( ) { static Fsm fsm; static LangEl lel[] = { {1, "one"}, {2, "two-a"}, {2, "two-b"}, {2, "two-c"}, {3, "three"} }; fsm.init(); fsm.execute( lel, 5 ); fsm.finish(); return 0; } #ifdef _____OUTPUT_____ one two-a two-b two-c three accept #endif ragel-6.10/test/cond3.rl0000664000175000017500000000162113065111230011771 00000000000000/* * @LANG: c++ */ #include #include using std::cout; using std::endl; %%{ machine foo; action hit_5 {c == 5} action done { cout << " done" << endl; } action inc {c++;} # The any* includes '\n' when hit_5 is true, so use guarded concatenation. main := (any @inc)* :> '\n' when hit_5 @done; }%% %% write data noerror; void test( const char *str ) { int cs = foo_start; int c = 0; const char *p = str; const char *pe = str + strlen( str ); cout << "run:" << endl; %% write exec; if ( cs >= foo_first_final ) cout << " success" << endl; else cout << " failure" << endl; cout << endl; } int main() { test( "12345\n" ); // success test( "\n2345\n" ); // success, first newline ignored test( "1234\n" ); // failure, didn't get 5 chars before newline. return 0; } #ifdef _____OUTPUT_____ run: done success run: done success run: failure #endif ragel-6.10/test/mailbox2.rl0000664000175000017500000000630513065111230012504 00000000000000/* * @LANG: c++ * @CFLAGS: -I../aapl */ #include #include using std::cin; using std::cout; using std::cerr; using std::endl; %%{ machine mailbox; action prn_char { cout << *p; } action prn_space { cout << ' '; } action prn_word { cout.write(ws, p-ws); cout << ' '; } action prn_addr1 { cout << "| "; cout.write(ws+1, p-ws-2); } action prn_addr2 { cout << "| "; cout.write(ws, p-ws); } action prn_tab { cout << '\t'; } action prn_nl { cout << '\n'; } action prn_separator { cout << "------\n"; } action prn_from { cout << "FROM\n"; } action prn_to { cout << "TO\n"; } action prn_subj { cout << "SUBJECT\n"; } action start_word { ws = p; } action start_headers { preserve = p; } action end_headers {preserve = 0;} day = upper lower{2}; month = upper lower{2}; year = digit{4}; time = digit{2} ':' digit{2} ( ':' digit{2} )?; letterZone = upper{3}; numZone = [+\-] digit{4}; zone = letterZone | numZone; dayNum = ( digit | ' ' ) digit; date = day ' ' month ' ' dayNum ' ' time ' ' ( year | year ' ' zone | zone ' ' year ); fromLine = 'From ' [^\n]* ' ' date '\n' @start_headers; headerChar = print - [ :]; headersToPrint = 'From' | 'To' | 'Subject'; headersToConsume = headerChar+ - headersToPrint; consumeHeader = headersToConsume ':' ( [^\n] | ( '\n' [ \t] ) )* '\n'; addrWS = ( [ \t]+ | '\n' [ \t]+ ); addrComment = '(' [^)]* ')'; addrWord = [^"'@,<>() \t\n]+; addrAddr1 = '<' [^>]* '>'; addrAddr2 = addrWord '@' addrWord; addrString = '"' [^"]* '"' | "'" [^']* "'"; addrItem = ( addrAddr1 %prn_addr1 | addrAddr2 %prn_addr2 | addrWord %prn_word | addrString %prn_word ) >start_word; address = ( addrWS | addrComment | addrItem )** >prn_tab; addrHeader = ( 'From' %prn_from | 'To' %prn_to ) ':' address ( ',' @prn_nl address )* '\n' %prn_nl; subjectHeader = 'Subject:' @prn_subj @prn_tab ' '* <: ( [^\n] @prn_char | ( '\n' [ \t]+ ) %prn_space )** '\n' %prn_nl; header = consumeHeader | addrHeader | subjectHeader; messageLine = ( [^\n]* '\n' - fromLine ); main := ( fromLine %prn_separator header* '\n' @end_headers messageLine* )*; }%% %% write data; #define BUFSIZE 8192 void test( const char *buf ) { int cs, len = strlen( buf ); const char *preserve = 0, *ws = 0; %% write init; const char *p = buf; const char *pe = p + len; %% write exec; if ( cs == mailbox_error ) cerr << "ERROR" << endl; if ( cs < mailbox_first_final ) cerr << "DID NOT FINISH IN A FINAL STATE" << endl; } int main() { test( "From user@host.com Wed Nov 28 13:30:05 2001\n" "From: \"Adrian D. Thurston\" \n" "Subject: the squirrel has landed\n" "\n" "Message goes here. \n" "From (trick from line).\n" "From: not really a header\n" "\n" "From user2@host2.com Wed Nov 28 13:30:05 2001\n" "To: Edgar Allen Poe (da man)\n" "Subject: (no subject) \n" "\n" "Message goes here. \n" "\n" ); return 0; } #ifdef _____OUTPUT_____ ------ FROM "Adrian D. Thurston" | thurston@complang.org SUBJECT the squirrel has landed ------ TO Edgar Allen Poe | ep@net.com SUBJECT (no subject) #endif ragel-6.10/test/mailbox3.rl0000664000175000017500000001216713065111230012510 00000000000000/* * @LANG: c++ * @CFLAGS: -I../aapl */ #include #include using std::cin; using std::cout; using std::cerr; using std::endl; %%{ machine mailbox; action prn_char { cout << *p; } action prn_space { cout << ' '; } action prn_word { cout.write(ws, p-ws); cout << ' '; } action prn_addr1 { cout << "| "; cout.write(ws+1, p-ws-2); } action prn_addr2 { cout << "| "; cout.write(ws, p-ws); } action prn_tab { cout << '\t'; } action prn_nl { cout << '\n'; } action prn_separator { cout << "------\n"; } action prn_from { cout << "FROM\n"; } action prn_to { cout << "TO\n"; } action prn_subj { cout << "SUBJECT\n"; } action start_word { ws = p; } action start_headers { preserve = p; } action end_headers {preserve = 0;} day = upper lower{2}; month = upper lower{2}; year = digit{4}; time = digit{2} ':' digit{2} ( ':' digit{2} )?; letterZone = upper{3}; numZone = [+\-] digit{4}; zone = letterZone | numZone; dayNum = ( digit | ' ' ) digit; date = day ' ' month ' ' dayNum ' ' time ' ' ( year | year ' ' zone | zone ' ' year ); fromLine = 'From ' [^\n]* ' ' date '\n' @start_headers; headerChar = print - [ :]; headersToPrint = 'From' | 'To' | 'Subject'; headersToConsume = headerChar+ - headersToPrint; action init_hlen {hlen = 0;} action hlen {hlen++ < 50} consumeHeaderBody = ':' @init_hlen ( [^\n] | ( '\n' [ \t] ) )* when hlen '\n'; consumeHeader = headersToConsume consumeHeaderBody; addrWS = ( [ \t]+ | '\n' [ \t]+ ); addrComment = '(' [^)]* ')'; addrWord = [^"'@,<>() \t\n]+; addrAddr1 = '<' [^>]* '>'; addrAddr2 = addrWord '@' addrWord; addrString = '"' [^"]* '"' | "'" [^']* "'"; addrItem = ( addrAddr1 %prn_addr1 | addrAddr2 %prn_addr2 | addrWord %prn_word | addrString %prn_word ) >start_word; address = ( addrWS | addrComment | addrItem )** >prn_tab; addrHeader = ( 'From' %prn_from | 'To' %prn_to ) ':' @init_hlen ( address ( ',' @prn_nl address )* ) when hlen '\n' %prn_nl; subjectHeader = 'Subject:' @prn_subj @prn_tab @init_hlen ( ' '* <: ( [^\n] @prn_char | ( '\n' [ \t]+ ) %prn_space )** ) when hlen '\n' %prn_nl; header = consumeHeader | addrHeader | subjectHeader; messageLine = ( [^\n]* when hlen '\n' @init_hlen ) - fromLine; main := ( fromLine %prn_separator header* '\n' @end_headers @init_hlen messageLine* )*; }%% %% write data; #define BUFSIZE 8192 void test( const char *buf ) { int cs, len = strlen( buf ); const char *preserve = 0, *ws = 0; int hlen = 0; %% write init; const char *p = buf; const char *pe = p + len; %% write exec; if ( cs < mailbox_first_final ) { cout << endl << endl; cout << "DID NOT FINISH IN A FINAL STATE" << endl; } } int main() { test( "From user@host.com Wed Nov 28 13:30:05 2001\n" "From: \"Adrian D. Thurston\" \n" "Subject: the squirrel has landed\n" "\n" "Message goes here. \n" "From (trick from line).\n" "From: not really a header\n" "\n" "From user2@host2.com Wed Nov 28 13:30:05 2001\n" "To: \"(kill 1)\" Edgar Allen Poe (da man)\n" "Subject: (no subject) this is a really long subject which should fail the length constraint \n" "Other: 0123456789\n" "\n" "Message goes here. \n" "\n" ); test( "From user@host.com Wed Nov 28 13:30:05 2001\n" "To: \"(kill 2)\" some guy \n" "From: \"Adrian D. Thurston this name is far too long\" \n" "Subject: the squirrel has landed\n" "\n" "From user2@host2.com Wed Nov 28 13:30:05 2001\n" "To: Edgar Allen Poe (da man)\n" "Subject: (no subject) \n" "\n" ); test( "From user@host.com Wed Nov 28 13:30:05 2001\n" "To: \"(kill 3)\" some guy \n" "From: \"Adrian D. Thurston This name is fore sure absolutely too long\" \n" "Subject: the squirrel has landed\n" "\n" ); test( "From user@host.com Wed Nov 28 13:30:05 2001\n" "From: \"Adrian D. Thurston \" \n" "Subject: (kill 4) the squirrel has landed\n" "Other: This is another header field, not interpreted, that is too long\n" "\n" ); test( "From user@host.com Wed Nov 28 13:30:05 2001\n" "From: \"Adrian D. Thurston \" \n" "Subject: (kill 5)the squirrel has landed\n" "\n" "This message line is okay.\n" "But this message line is far too long and will cause an error.\n" ); return 0; } #ifdef _____OUTPUT_____ ------ FROM "Adrian D. Thurston" | thurston@complang.org SUBJECT the squirrel has landed ------ TO "(kill 1)" Edgar Allen Poe | ep@net.com SUBJECT (no subject) this is a really long subject whic DID NOT FINISH IN A FINAL STATE ------ TO "(kill 2)" some guy | sg@net.com FROM "Adrian D. Thurston this name is far too long" DID NOT FINISH IN A FINAL STATE ------ TO "(kill 3)" some guy | sg@net.com FROM DID NOT FINISH IN A FINAL STATE ------ FROM "Adrian D. Thurston " | t@cs.ca SUBJECT (kill 4) the squirrel has landed DID NOT FINISH IN A FINAL STATE ------ FROM "Adrian D. Thurston " | t@cs.ca SUBJECT (kill 5)the squirrel has landed DID NOT FINISH IN A FINAL STATE #endif ragel-6.10/test/erract2.rl0000664000175000017500000000215313065111230012326 00000000000000/* * @LANG: indep * * Test error actions. */ %% %%{ machine ErrAct; action err_start { prints "err_start\n"; } action err_all { prints "err_all\n"; } action err_middle { prints "err_middle\n"; } action err_out { prints "err_out\n"; } action eof_start { prints "eof_start\n"; } action eof_all { prints "eof_all\n"; } action eof_middle { prints "eof_middle\n"; } action eof_out { prints "eof_out\n"; } main := ( 'hello' >err err_start $err err_all <>err err_middle %err err_out >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out ) '\n'; }%% /* _____INPUT_____ "" "h" "x" "he" "hx" "hel" "hex" "hell" "helx" "hello" "hellx" "hello\n" "hellox" _____INPUT_____ */ /* _____OUTPUT_____ err_start eof_start err_all eof_all FAIL err_all err_middle eof_all eof_middle FAIL err_start err_all FAIL err_all err_middle eof_all eof_middle FAIL err_all err_middle FAIL err_all err_middle eof_all eof_middle FAIL err_all err_middle FAIL err_all err_middle eof_all eof_middle FAIL err_all err_middle FAIL err_all err_out eof_all eof_out FAIL err_all err_middle FAIL ACCEPT err_all err_out FAIL _____OUTPUT_____ */ ragel-6.10/test/checkeofact.txl0000664000175000017500000000270613065111230013421 00000000000000include "testcase.txl" define program [lang_indep] | 'yes | 'no end define rule findEof1 match [machine_expr_item] '>/ end rule rule findEof2 match [machine_expr_item] '/ end rule rule findEof7 match [repeat machine_expr_item] '> 'eof _ [repeat machine_expr_item] end rule rule findEof8 match [repeat machine_expr_item] '< 'eof _ [repeat machine_expr_item] end rule rule findEof9 match [repeat machine_expr_item] '$ 'eof _ [repeat machine_expr_item] end rule rule findEof10 match [repeat machine_expr_item] '% 'eof _ [repeat machine_expr_item] end rule rule findEof11 match [repeat machine_expr_item] '@ 'eof _ [repeat machine_expr_item] end rule rule findEof12 match [repeat machine_expr_item] '<> 'eof _ [repeat machine_expr_item] end rule rule findScanner match [machine_expr_item] '|* _ [repeat scanner_item] '*| end rule function findEof P [program] replace [program] _ [program] where P [findEof1] [findEof2] [findEof3] [findEof4] [findEof5] [findEof6] [findEof7] [findEof8] [findEof9] [findEof10] [findEof11] [findEof12] [findScanner] by 'yes end function function main replace [program] P [program] construct NewP [program] 'no by NewP [findEof P] end function ragel-6.10/test/cond5.rl0000664000175000017500000000245513065111230012001 00000000000000/* * @LANG: c++ */ #include #include using std::cout; using std::endl; %%{ machine foo; write data noerror; }%% void test( const char *str ) { int cs = foo_start; int c = 0; const char *p = str; const char *pe = str + strlen( str ); char last = '0'; cout << "run:"; %%{ action d1 { cout << " d1"; } action see_five { cout << " see_five"; } see_five = ([0-9] when{c++ < 5} @d1)* '\n' @see_five; action in_sequence { cout << " in_sequence"; } action d2 { last = *p; cout << " d2"; } in_sequence = ( [0-9] when { *p == last+1 } @d2 )* '\n' @in_sequence; main := ( see_five | in_sequence ) ${cout << " |";}; write exec; }%% if ( cs < foo_first_final ) cout << " failure"; cout << endl; } int main() { test( "123456789012\n" ); // fails both test( "123456789\n" ); // fails five test( "1234\n" ); // fails five test( "13245\n" ); // fails sequence test( "12345\n" ); // succeeds in both return 0; } #ifdef _____OUTPUT_____ run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | d1 d2 | d2 | d2 | d2 | d2 | failure run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | d1 d2 | d2 | d2 | d2 | d2 | in_sequence | run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | see_five in_sequence | run: d1 d2 | d1 | d1 | d1 | d1 | see_five | run: d1 d2 | d1 d2 | d1 d2 | d1 d2 | d1 d2 | see_five in_sequence | #endif ragel-6.10/test/cppscan1.rl0000664000175000017500000001650213065111230012477 00000000000000/* * @LANG: c++ * * Test works with split code gen. */ #include "cppscan1.h" %%{ machine Scanner; access fsm->; action pass { fsm->pass(fc); } action buf { fsm->buf(fc); } action emit_slit { fsm->token( TK_Slit ); } action emit_dlit { fsm->token( TK_Dlit ); } action emit_id { fsm->token( TK_Id ); } action emit_integer_decimal { fsm->token( TK_IntegerDecimal ); } action emit_integer_octal { fsm->token( TK_IntegerOctal ); } action emit_integer_hex { fsm->token( TK_IntegerHex ); } action emit_float { fsm->token( TK_Float ); } action emit_symbol { fsm->token( fsm->tokBuf.data[0] ); } action tokst { fsm->tokStart = fsm->col; } # Single and double literals. slit = ( 'L'? ( "'" ( [^'\\\n] | /\\./ )* "'" ) $buf ) >tokst %emit_slit; dlit = ( 'L'? ( '"' ( [^"\\\n] | /\\./ )* '"' ) $buf ) >tokst %emit_dlit; # Identifiers id = ( [a-zA-Z_] [a-zA-Z0-9_]* ) >tokst $buf %emit_id; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; float = ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) >tokst $buf %emit_float; # Integer decimal. Leading part buffered by float. integer_decimal = ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} $buf ) %emit_integer_decimal; # Integer octal. Leading part buffered by float. integer_octal = ( '0' [0-9]+ [ulUL]{0,2} $buf ) %emit_integer_octal; # Integer hex. Leading 0 buffered by float. integer_hex = ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) $buf ) %emit_integer_hex; # Only buffer the second item, first buffered by symbol. */ namesep = '::' @buf %{fsm->token( TK_NameSep );}; deqs = '==' @buf %{fsm->token( TK_EqualsEquals );}; neqs = '!=' @buf %{fsm->token( TK_NotEquals );}; and_and = '&&' @buf %{fsm->token( TK_AndAnd );}; or_or = '||' @buf %{fsm->token( TK_OrOr );}; mult_assign = '*=' @buf %{fsm->token( TK_MultAssign );}; percent_assign = '%=' @buf %{fsm->token( TK_PercentAssign );}; plus_assign = '+=' @buf %{fsm->token( TK_PlusAssign );}; minus_assign = '-=' @buf %{fsm->token( TK_MinusAssign );}; amp_assign = '&=' @buf %{fsm->token( TK_AmpAssign );}; caret_assign = '^=' @buf %{fsm->token( TK_CaretAssign );}; bar_assign = '|=' @buf %{fsm->token( TK_BarAssign );}; plus_plus = '++' @buf %{fsm->token( TK_PlusPlus );}; minus_minus = '--' @buf %{fsm->token( TK_MinusMinus );}; arrow = '->' @buf %{fsm->token( TK_Arrow );}; arrow_star = '->*' @buf %{fsm->token( TK_ArrowStar );}; dot_star = '.*' @buf %{fsm->token( TK_DotStar );}; # Buffer both items. * div_assign = '/=' @{fsm->buf('/');fsm->buf(fc);} %{fsm->token( TK_DivAssign );}; # Double dot is sent as two dots. dot_dot = '..' %{fsm->token('.'); fsm->buf('.'); fsm->token('.');}; # Three char compounds, first item already buffered. */ dot_dot_dot = '...' %{fsm->buf('.'); fsm->buf('.'); fsm->token( TK_DotDotDot );}; # All compunds compound = namesep | deqs | neqs | and_and | or_or | mult_assign | div_assign | percent_assign | plus_assign | minus_assign | amp_assign | caret_assign | bar_assign | plus_plus | minus_minus | arrow | arrow_star | dot_star | dot_dot | dot_dot_dot; # Single char symbols. symbol = ( punct - [./_"'] ) >tokst $buf %emit_symbol | # Do not immediately buffer slash, may be start of comment. '/' >tokst %{ fsm->buf('/'); fsm->token( '/' ); } | # Dot covered by float. '.' %emit_symbol; # Comments and whitespace. commc = '/*' @{fsm->pass('/'); fsm->pass('*');} ( any* $0 '*/' @1 ) $pass; commcc = '//' @{fsm->pass('/'); fsm->pass('/');} ( any* $0 '\n' @1 ) $pass; whitespace = ( any - ( 0 | 33..126 ) )+ $pass; action onEOFChar { /* On EOF char, write out the non token buffer. */ fsm->nonTokBuf.append(0); cout << fsm->nonTokBuf.data; fsm->nonTokBuf.clear(); } # Using 0 as eof. If seeingAs a result all null characters get ignored. EOF = 0 @onEOFChar; # All outside code tokens. tokens = ( id | slit | dlit | float | integer_decimal | integer_octal | integer_hex | compound | symbol ); nontok = ( commc | commcc | whitespace | EOF ); position = ( '\n' @{ fsm->line += 1; fsm->col = 1; } | [^\n] @{ fsm->col += 1; } )*; main := ( ( tokens | nontok )** ) & position; }%% %% write data; void Scanner::init( ) { Scanner *fsm = this; /* A count of the number of characters in * a token. Used for % sequences. */ count = 0; line = 1; col = 1; %% write init; } int Scanner::execute( const char *data, int len ) { Scanner *fsm = this; const char *p = data; const char *pe = data + len; const char *eof = pe; %% write exec; if ( cs == Scanner_error ) return -1; if ( cs >= Scanner_first_final ) return 1; return 0; } int Scanner::finish( ) { if ( cs == Scanner_error ) return -1; if ( cs >= Scanner_first_final ) return 1; return 0; } void Scanner::token( int id ) { /* Leader. */ if ( nonTokBuf.length > 0 ) { nonTokBuf.append(0); cout << nonTokBuf.data; nonTokBuf.clear(); } /* Token data. */ tokBuf.append(0); cout << '<' << id << '>' << tokBuf.data; tokBuf.clear(); } void Buffer::empty() { if ( data != 0 ) { free( data ); data = 0; length = 0; allocated = 0; } } void Buffer::upAllocate( int len ) { if ( data == 0 ) data = (char*) malloc( len ); else data = (char*) realloc( data, len ); allocated = len; } void test( const char *buf ) { Scanner scanner(cout); scanner.init(); scanner.execute( buf, strlen(buf) ); /* The last token is ignored (because there is no next token). Send * trailing null to force the last token into whitespace. */ char eof = 0; if ( scanner.execute( &eof, 1 ) <= 0 ) { cerr << "cppscan: scan failed" << endl; return; } cout.flush(); } int main() { test( "/*\n" " * Copyright \n" " */\n" "\n" "/* Construct an fsmmachine from a graph. */\n" "RedFsmAp::RedFsmAp( FsmAp *graph, bool complete )\n" ":\n" " graph(graph),\n" "{\n" " assert( sizeof(RedTransAp) <= sizeof(TransAp) );\n" "\n" " reduceMachine();\n" "}\n" "\n" "{\n" " /* Get the transition that we want to extend. */\n" " RedTransAp *extendTrans = list[pos].value;\n" "\n" " /* Look ahead in the transition list. */\n" " for ( int next = pos + 1; next < list.length(); pos++, next++ ) {\n" " if ( ! keyOps->eq( list[pos].highKey, nextKey ) )\n" " break;\n" " }\n" " return false;\n" "}\n" "\n" ); test( "->*\n" ".*\n" "/*\"*/\n" "\"/*\"\n" "L'\"'\n" "L\"'\"\n" ); return 0; } #ifdef _____OUTPUT_____ /* * Copyright */ /* Construct an fsmmachine from a graph. */ <195>RedFsmAp<197>::<195>RedFsmAp<40>( <195>FsmAp <42>*<195>graph<44>, <195>bool <195>complete <41>) <58>: <195>graph<40>(<195>graph<41>)<44>, <123>{ <195>assert<40>( <195>sizeof<40>(<195>RedTransAp<41>) <60><<61>= <195>sizeof<40>(<195>TransAp<41>) <41>)<59>; <195>reduceMachine<40>(<41>)<59>; <125>} <123>{ /* Get the transition that we want to extend. */ <195>RedTransAp <42>*<195>extendTrans <61>= <195>list<91>[<195>pos<93>]<46>.<195>value<59>; /* Look ahead in the transition list. */ <195>for <40>( <195>int <195>next <61>= <195>pos <43>+ <218>1<59>; <195>next <60>< <195>list<46>.<195>length<40>(<41>)<59>; <195>pos<212>++<44>, <195>next<212>++ <41>) <123>{ <195>if <40>( <33>! <195>keyOps<211>-><195>eq<40>( <195>list<91>[<195>pos<93>]<46>.<195>highKey<44>, <195>nextKey <41>) <41>) <195>break<59>; <125>} <195>return <195>false<59>; <125>} <214>->* <215>.* /*"*/ <192>"/*" <193>L'"' <192>L"'" #endif ragel-6.10/test/awkemu.rl0000664000175000017500000000612313065111230012256 00000000000000/* * @LANG: c */ /* * Emulate the basic parser of the awk program. Breaks lines up into * words and prints the words. */ #include #include #define LINEBUF 2048 static char lineBuf[LINEBUF]; static char blineBuf[LINEBUF]; static int lineLen; static int blineLen; static int words; void finishLine(); struct awkemu { int cs; }; %%{ machine awkemu; variable cs fsm->cs; # Starts a line. Will initialize all the data necessary for capturing the line. action startline { lineLen = 0; blineLen = 0; words = 0; } # Will be executed on every character seen in a word. Captures the word # to the broken up line buffer. action wordchar { blineBuf[blineLen++] = fc; } # Terminate a word. Adds the null after the word and increments the word count # for the line. action termword { blineBuf[blineLen++] = 0; words += 1; } # Will be executed on every character seen in a line (not including # the newline itself. action linechar { lineBuf[lineLen++] = fc; } # This section of the machine deals with breaking up lines into fields. # Lines are separed by the whitespace and put in an array of words. # Words in a line. word = (extend - [ \t\n])+; # The whitespace separating words in a line. whitespace = [ \t]; # The components in a line to break up. Either a word or a single char of # whitespace. On the word capture characters. blineElements = word $wordchar %termword | whitespace; # Star the break line elements. Just be careful to decrement the leaving # priority as we don't want multiple character identifiers to be treated as # multiple single char identifiers. breakLine = ( blineElements $1 %0 )* . '\n'; # This machine lets us capture entire lines. We do it separate from the words # in a line. bufLine = (extend - '\n')* $linechar %{ finishLine(); } . '\n'; # A line can then consist of the machine that will break up the line into # words and a machine that will buffer the entire line. line = ( breakLine | bufLine ) > startline; # Any number of lines. main := line*; }%% void finishLine() { int i; char *pword = blineBuf; lineBuf[lineLen] = 0; printf("endline(%i): %s\n", words, lineBuf ); for ( i = 0; i < words; i++ ) { printf(" word: %s\n", pword ); pword += strlen(pword) + 1; } } %% write data; void awkemu_init( struct awkemu *fsm ) { %% write init; } void awkemu_execute( struct awkemu *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int awkemu_finish( struct awkemu *fsm ) { if ( fsm->cs == awkemu_error ) return -1; if ( fsm->cs >= awkemu_first_final ) return 1; return 0; } #include #define BUFSIZE 2048 struct awkemu fsm; char buf[BUFSIZE]; void test( char *buf ) { int len = strlen( buf ); awkemu_init( &fsm ); awkemu_execute( &fsm, buf, len ); if ( awkemu_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "" ); test( "one line with no newline" ); test( "one line\n" ); return 0; } #ifdef _____OUTPUT_____ ACCEPT FAIL endline(2): one line word: one word: line ACCEPT #endif ragel-6.10/test/fnext1.rl0000664000175000017500000000200513065111230012165 00000000000000/* * @LANG: c * * Tests fnext in combination with fbreak. */ #include #include char comm; int top; int stack [32]; %%{ machine fnext; action break {fbreak;} main := 'h' @{ /*h*/ fnext e; fbreak; }; e := 'e' @{ /*e*/ fnext l; } @{ fbreak; }; l := 'll' @{ /*ll*/ fnext o; } ${ fbreak; }; o := |* 'o' { /*o*/ fnext nl; fbreak; }; *|; nl := '\n' @{ /*nl*/ fbreak; printf("ACCEPT\n"); }; }%% int cs; char *ts, *te; int act; %% write data; void init() { %% write init; } void exec( char *data, int len ) { char *p = data; char *pe = data + len; while ( cs != fnext_error && p < pe ) { printf( "%c\n", *p ); %% write exec; } } void finish( ) { if ( cs >= fnext_first_final ) printf( "ACCEPT\n" ); else printf( "FAIL\n" ); } char *inp[] = { "hello\n" }; int inplen = 1; int main( ) { int i; for ( i = 0; i < inplen; i++ ) { init(); exec( inp[i], strlen(inp[i]) ); finish(); } return 0; } #ifdef _____OUTPUT_____ h e l l o ACCEPT #endif ragel-6.10/test/scan2.rl0000664000175000017500000000067613065111230012002 00000000000000/* * @LANG: indep */ ptr ts; ptr te; int act; int token; %% %%{ machine scanner; # Warning: changing the patterns or the input string will affect the # coverage of the scanner action types. main := |* 'a' => { prints "pat1\n"; }; [ab]+ . 'c' => { prints "pat2\n"; }; any => { prints "any\n"; }; *|; }%% /* _____INPUT_____ "a" _____INPUT_____ */ /* _____OUTPUT_____ pat1 ACCEPT _____OUTPUT_____ */ ragel-6.10/test/langtrans_d.sh0000775000175000017500000000333313065111230013261 00000000000000#!/bin/bash # file=$1 [ -f $file ] || exit 1 # Get the amchine name. machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' $file` # Make a temporary version of the test case the D language translations. sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_d.txl > $file.pr # Begin writing out the test case. cat << EOF /* * @LANG: d * @GENERATED: yes EOF grep '@ALLOW_GENFLAGS:' $file grep '@ALLOW_MINFLAGS:' $file cat << EOF */ import std.stdio; import std.string; class $machine { EOF # Write the data declarations sed -n '/^%%$/q;{s/^/\t/;p}' $file.pr # Write out the machine specification. sed -n '/^%%{$/,/^}%%/{s/^/\t/;p}' $file.pr # Write out the init and execute routines. cat << EOF int cs; %% write data; void init() { EOF sed -n '0,/^%%$/d; /^%%{$/q; {s/^/\t\t/;p}' $file.pr cat << EOF %% write init; } void exec( char data[] ) { char *p = data.ptr; char *pe = data.ptr + data.length; char *eof = pe; char _s[]; %% write exec; } void finish( ) { if ( cs >= ${machine}_first_final ) writefln( "ACCEPT" ); else writefln( "FAIL" ); } EOF # Write out the test data. sed -n '0,/\/\* _____INPUT_____/d; /_____INPUT_____ \*\//q; p;' $file | awk ' BEGIN { print " char[][] inp = [" } { print " " $0 "," } END { print " ];" print "" print " int inplen = " NR ";" }' # Write out the main routine. cat << EOF } int main( ) { $machine m = new $machine(); int i; for ( i = 0; i < m.inplen; i++ ) { m.init(); m.exec( m.inp[i] ); m.finish(); } return 0; } /* _____OUTPUT_____ EOF # Write out the expected output. sed -n '0,/\/\* _____OUTPUT_____/d; /_____OUTPUT_____ \*\//q; p;' $file echo "*/" # Don't need this language-specific file anymore. rm $file.pr ragel-6.10/test/minimize1.rl0000664000175000017500000000171713065111230012673 00000000000000/* * @LANG: c */ #include #include struct min { int cs; }; %%{ machine min; variable cs fsm->cs; action a_or_b { printf("a or b\n"); } main := ( ( 'a' . [ab]* @a_or_b ) | ( 'b' . [ab]* @a_or_b ) ) . '\n'; }%% %% write data; void min_init( struct min *fsm ) { %% write init; } void min_execute( struct min *fsm, const char *_data, int _len ) { const char *p = _data; const char *pe = _data+_len; %% write exec; } int min_finish( struct min *fsm ) { if ( fsm->cs == min_error ) return -1; if ( fsm->cs >= min_first_final ) return 1; return 0; } struct min fsm; void test( char *buf ) { int len = strlen( buf ); min_init( &fsm ); min_execute( &fsm, buf, len ); if ( min_finish( &fsm ) > 0 ) printf("ACCEPT\n"); else printf("FAIL\n"); } int main() { test( "aaaaaa\n" ); test( "a\n" ); test( "abc\n" ); return 0; } #ifdef _____OUTPUT_____ a or b a or b a or b a or b a or b ACCEPT ACCEPT a or b FAIL #endif ragel-6.10/test/export1.rl0000664000175000017500000000144213065111230012366 00000000000000/* * @LANG: c */ #include #include %%{ machine test; export c1 = 'c'; export c2 = 'z'; export c3 = 't'; commands := ( c1 . digit* '\n' @{ printf( "c1\n" );} | c2 . alpha* '\n' @{ printf( "c2\n" );}| c3 . '.'* '\n' @{ printf( "c3\n" );} )*; some_other := any*; }%% %% write exports; %% write data; int test( const char *data, int len ) { int cs = test_en_commands; const char *p = data, *pe = data + len; %% write init nocs; %% write exec; if ( cs >= test_first_final ) printf("ACCEPT\n"); else printf("ERROR\n"); return 0; } char data[] = { test_ex_c1, '1', '2', '\n', test_ex_c2, 'a', 'b', '\n', test_ex_c3, '.', '.', '\n', 0 }; int main() { test( data, strlen( data ) ); return 0; } #ifdef _____OUTPUT_____ c1 c2 c3 ACCEPT #endif ragel-6.10/test/xml.rl0000664000175000017500000001540713065111230011572 00000000000000/* * XML parser based on the XML 1.0 BNF from: * http://www.jelks.nu/XML/xmlebnf.html * * @LANG: c++ * @ALLOW_MINFLAGS: -l -e * @ALLOW_GENFLAGS: -T0 -T1 */ #include #include #include using namespace std; #define BUFSIZE 2048 struct XML { int cur_char; int start_word; int start_comment; int start_literal; int cs, top, stack[1024]; int init( ); int execute( const unsigned short *data, int len ); int finish( ); }; %%{ machine XML; alphtype unsigned short; action next_char { cur_char += 1; } action start_word { start_word = cur_char; } action end_word { cout << "word: " << start_word << " " << cur_char-1 << endl; } Extender = 0x00B7 | 0x02D0 | 0x02D1 | 0x0387 | 0x0640 | 0x0E46 | 0x0EC6 | 0x3005 | (0x3031..0x3035) | (0x309D..0x309E) | (0x30FC..0x30FE); Digit = (0x0030..0x0039) | (0x0660..0x0669) | (0x06F0..0x06F9) | (0x0966..0x096F) | (0x09E6..0x09EF) | (0x0A66..0x0A6F) | (0x0AE6..0x0AEF) | (0x0B66..0x0B6F) | (0x0BE7..0x0BEF) | (0x0C66..0x0C6F) | (0x0CE6..0x0CEF) | (0x0D66..0x0D6F) | (0x0E50..0x0E59) | (0x0ED0..0x0ED9) | (0x0F20..0x0F29); CombiningChar = (0x0300..0x0345) | (0x0360..0x0361) | (0x0483..0x0486) | (0x0591..0x05A1) | (0x05A3..0x05B9) | (0x05BB..0x05BD) | 0x05BF | (0x05C1..0x05C2) | 0x05C4 | (0x064B..0x0652) | 0x0670 | (0x06D6..0x06DC) | (0x06DD..0x06DF) | (0x06E0..0x06E4) | (0x06E7..0x06E8) | (0x06EA..0x06ED) | (0x0901..0x0903) | 0x093C | (0x093E..0x094C) | 0x094D | (0x0951..0x0954) | (0x0962..0x0963) | (0x0981..0x0983) | 0x09BC | 0x09BE | 0x09BF | (0x09C0..0x09C4) | (0x09C7..0x09C8) | (0x09CB..0x09CD) | 0x09D7 | (0x09E2..0x09E3) | 0x0A02 | 0x0A3C | 0x0A3E | 0x0A3F | (0x0A40..0x0A42) | (0x0A47..0x0A48) | (0x0A4B..0x0A4D) | (0x0A70..0x0A71) | (0x0A81..0x0A83) | 0x0ABC | (0x0ABE..0x0AC5) | (0x0AC7..0x0AC9) | (0x0ACB..0x0ACD) | (0x0B01..0x0B03) | 0x0B3C | (0x0B3E..0x0B43) | (0x0B47..0x0B48) | (0x0B4B..0x0B4D) | (0x0B56..0x0B57) | (0x0B82..0x0B83) | (0x0BBE..0x0BC2) | (0x0BC6..0x0BC8) | (0x0BCA..0x0BCD) | 0x0BD7 | (0x0C01..0x0C03) | (0x0C3E..0x0C44) | (0x0C46..0x0C48) | (0x0C4A..0x0C4D) | (0x0C55..0x0C56) | (0x0C82..0x0C83) | (0x0CBE..0x0CC4) | (0x0CC6..0x0CC8) | (0x0CCA..0x0CCD) | (0x0CD5..0x0CD6) | (0x0D02..0x0D03) | (0x0D3E..0x0D43) | (0x0D46..0x0D48) | (0x0D4A..0x0D4D) | 0x0D57 | 0x0E31 | (0x0E34..0x0E3A) | (0x0E47..0x0E4E) | 0x0EB1 | (0x0EB4..0x0EB9) | (0x0EBB..0x0EBC) | (0x0EC8..0x0ECD) | (0x0F18..0x0F19) | 0x0F35 | 0x0F37 | 0x0F39 | 0x0F3E | 0x0F3F | (0x0F71..0x0F84) | (0x0F86..0x0F8B) | (0x0F90..0x0F95) | 0x0F97 | (0x0F99..0x0FAD) | (0x0FB1..0x0FB7) | 0x0FB9 | (0x20D0..0x20DC) | 0x20E1 | (0x302A..0x302F) | 0x3099 | 0x309A; Ideographic = (0x4E00..0x9FA5) | 0x3007 | (0x3021..0x3029); BaseChar = (0x0041..0x005A) | (0x0061..0x007A) | (0x00C0..0x00D6) | (0x00D8..0x00F6) | (0x00F8..0x00FF) | (0x0100..0x0131) | (0x0134..0x013E) | (0x0141..0x0148) | (0x014A..0x017E) | (0x0180..0x01C3) | (0x01CD..0x01F0) | (0x01F4..0x01F5) | (0x01FA..0x0217) | (0x0250..0x02A8) | (0x02BB..0x02C1) | 0x0386 | (0x0388..0x038A) | 0x038C | (0x038E..0x03A1) | (0x03A3..0x03CE) | (0x03D0..0x03D6) | 0x03DA | 0x03DC | 0x03DE | 0x03E0 | (0x03E2..0x03F3) | (0x0401..0x040C) | (0x040E..0x044F) | (0x0451..0x045C) | (0x045E..0x0481) | (0x0490..0x04C4) | (0x04C7..0x04C8) | (0x04CB..0x04CC) | (0x04D0..0x04EB) | (0x04EE..0x04F5) | (0x04F8..0x04F9) | (0x0531..0x0556) | 0x0559 | (0x0561..0x0586) | (0x05D0..0x05EA) | (0x05F0..0x05F2) | (0x0621..0x063A) | (0x0641..0x064A) | (0x0671..0x06B7) | (0x06BA..0x06BE) | (0x06C0..0x06CE) | (0x06D0..0x06D3) | 0x06D5 | (0x06E5..0x06E6) | (0x0905..0x0939) | 0x093D | (0x0958..0x0961) | (0x0985..0x098C) | (0x098F..0x0990) | (0x0993..0x09A8) | (0x09AA..0x09B0) | 0x09B2 | (0x09B6..0x09B9) | (0x09DC..0x09DD) | (0x09DF..0x09E1) | (0x09F0..0x09F1) | (0x0A05..0x0A0A) | (0x0A0F..0x0A10) | (0x0A13..0x0A28) | (0x0A2A..0x0A30) | (0x0A32..0x0A33) | (0x0A35..0x0A36) | (0x0A38..0x0A39) | (0x0A59..0x0A5C) | 0x0A5E | (0x0A72..0x0A74) | (0x0A85..0x0A8B) | 0x0A8D | (0x0A8F..0x0A91) | (0x0A93..0x0AA8) | (0x0AAA..0x0AB0) | (0x0AB2..0x0AB3) | (0x0AB5..0x0AB9) | 0x0ABD | 0x0AE0 | (0x0B05..0x0B0C) | (0x0B0F..0x0B10) | (0x0B13..0x0B28) | (0x0B2A..0x0B30) | (0x0B32..0x0B33) | (0x0B36..0x0B39) | 0x0B3D | (0x0B5C..0x0B5D) | (0x0B5F..0x0B61) | (0x0B85..0x0B8A) | (0x0B8E..0x0B90) | (0x0B92..0x0B95) | (0x0B99..0x0B9A) | 0x0B9C | (0x0B9E..0x0B9F) | (0x0BA3..0x0BA4) | (0x0BA8..0x0BAA) | (0x0BAE..0x0BB5) | (0x0BB7..0x0BB9) | (0x0C05..0x0C0C) | (0x0C0E..0x0C10) | (0x0C12..0x0C28) | (0x0C2A..0x0C33) | (0x0C35..0x0C39) | (0x0C60..0x0C61) | (0x0C85..0x0C8C) | (0x0C8E..0x0C90) | (0x0C92..0x0CA8) | (0x0CAA..0x0CB3) | (0x0CB5..0x0CB9) | 0x0CDE | (0x0CE0..0x0CE1) | (0x0D05..0x0D0C) | (0x0D0E..0x0D10) | (0x0D12..0x0D28) | (0x0D2A..0x0D39) | (0x0D60..0x0D61) | (0x0E01..0x0E2E) | 0x0E30 | (0x0E32..0x0E33) | (0x0E40..0x0E45) | (0x0E81..0x0E82) | 0x0E84 | (0x0E87..0x0E88) | 0x0E8A | 0x0E8D | (0x0E94..0x0E97) | (0x0E99..0x0E9F) | (0x0EA1..0x0EA3) | 0x0EA5 | 0x0EA7 | (0x0EAA..0x0EAB) | (0x0EAD..0x0EAE) | 0x0EB0 | (0x0EB2..0x0EB3) | 0x0EBD | (0x0EC0..0x0EC4) | (0x0F40..0x0F47) | (0x0F49..0x0F69) | (0x10A0..0x10C5) | (0x10D0..0x10F6) | 0x1100 | (0x1102..0x1103) | (0x1105..0x1107) | 0x1109 | (0x110B..0x110C) | (0x110E..0x1112) | 0x113C | 0x113E | 0x1140 | 0x114C | 0x114E | 0x1150 | (0x1154..0x1155) | 0x1159 | (0x115F..0x1161) | 0x1163 | 0x1165 | 0x1167 | 0x1169 | (0x116D..0x116E) | (0x1172..0x1173) | 0x1175 | 0x119E | 0x11A8 | 0x11AB | (0x11AE..0x11AF) | (0x11B7..0x11B8) | 0x11BA | (0x11BC..0x11C2) | 0x11EB | 0x11F0 | 0x11F9 | (0x1E00..0x1E9B) | (0x1EA0..0x1EF9) | (0x1F00..0x1F15) | (0x1F18..0x1F1D) | (0x1F20..0x1F45) | (0x1F48..0x1F4D) | (0x1F50..0x1F57) | 0x1F59 | 0x1F5B | 0x1F5D | (0x1F5F..0x1F7D) | (0x1F80..0x1FB4) | (0x1FB6..0x1FBC) | 0x1FBE | (0x1FC2..0x1FC4) | (0x1FC6..0x1FCC) | (0x1FD0..0x1FD3) | (0x1FD6..0x1FDB) | (0x1FE0..0x1FEC) | (0x1FF2..0x1FF4) | (0x1FF6..0x1FFC) | 0x2126 | (0x212A..0x212B) | 0x212E | (0x2180..0x2182) | (0x3041..0x3094) | (0x30A1..0x30FA) | (0x3105..0x312C) | (0xAC00..0xD7A3); # Full Unicode 3.1 requires: Char = 0x9 | 0xA | 0xD | (0x20..0xD7FF) | (0xE000..0xFFFD) | (0x10000..0x10FFFF); Char = 0x9 | 0xA | 0xD | (0x20..0xD7FF) | (0xE000..0xFFFD); Letter = BaseChar | Ideographic; NameChar = Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender; include CommonXml "xmlcommon.rl"; }%% %% write data; int XML::init( ) { %% write init; cur_char = 0; return 1; } int XML::execute( const unsigned short *data, int len ) { const unsigned short *p = data; const unsigned short *pe = data + len; %% write exec; if ( cs == XML_error ) return -1; if ( cs >= XML_first_final ) return 1; return 0; } int XML::finish( ) { if ( cs == XML_error ) return -1; if ( cs >= XML_first_final ) return 1; return 0; } int main() { return 0; } /* _____OUTPUT_____ _____OUTPUT_____ */ ragel-6.10/test/cppscan2.rl0000664000175000017500000001710613065111230012501 00000000000000/* * @LANG: c++ */ #include #include using namespace std; #define TK_Dlit 192 #define TK_Slit 193 #define TK_Float 194 #define TK_Id 195 #define TK_NameSep 197 #define TK_Arrow 211 #define TK_PlusPlus 212 #define TK_MinusMinus 213 #define TK_ArrowStar 214 #define TK_DotStar 215 #define TK_ShiftLeft 216 #define TK_ShiftRight 217 #define TK_IntegerDecimal 218 #define TK_IntegerOctal 219 #define TK_IntegerHex 220 #define TK_EqualsEquals 223 #define TK_NotEquals 224 #define TK_AndAnd 225 #define TK_OrOr 226 #define TK_MultAssign 227 #define TK_DivAssign 228 #define TK_PercentAssign 229 #define TK_PlusAssign 230 #define TK_MinusAssign 231 #define TK_AmpAssign 232 #define TK_CaretAssign 233 #define TK_BarAssign 234 #define TK_DotDotDot 240 #define TK_Whitespace 241 #define TK_Comment 242 #define BUFSIZE 4096 int tok; char buf[BUFSIZE]; const char *ts, *te; void token( const char *data, int len ); bool discard = false; struct Scanner { 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. int 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. int 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 Scanner; # Single and double literals. slit = ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) @{tok = TK_Slit;}; dlit = ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) @{tok = TK_Dlit;}; # Identifiers id = ( [a-zA-Z_] [a-zA-Z0-9_]* ) @{tok = TK_Id;}; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; float = ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) @{tok = TK_Float;}; # Integer decimal. Leading part buffered by float. integer_decimal = ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) @{tok = TK_IntegerDecimal;}; # Integer octal. Leading part buffered by float. integer_octal = ( '0' [0-9]+ [ulUL]{0,2} ) @{tok = TK_IntegerOctal;}; # Integer hex. Leading 0 buffered by float. integer_hex = ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) @{tok = TK_IntegerHex;}; # Only buffer the second item, first buffered by symbol. */ namesep = '::' @{tok = TK_NameSep;}; deqs = '==' @{tok = TK_EqualsEquals;}; neqs = '!=' @{tok = TK_NotEquals;}; and_and = '&&' @{tok = TK_AndAnd;}; or_or = '||' @{tok = TK_OrOr;}; mult_assign = '*=' @{tok = TK_MultAssign;}; div_assign = '/=' @{tok = TK_DivAssign;}; percent_assign = '%=' @{tok = TK_PercentAssign;}; plus_assign = '+=' @{tok = TK_PlusAssign;}; minus_assign = '-=' @{tok = TK_MinusAssign;}; amp_assign = '&=' @{tok = TK_AmpAssign;}; caret_assign = '^=' @{tok = TK_CaretAssign;}; bar_assign = '|=' @{tok = TK_BarAssign;}; plus_plus = '++' @{tok = TK_PlusPlus;}; minus_minus = '--' @{tok = TK_MinusMinus;}; arrow = '->' @{tok = TK_Arrow;}; arrow_star = '->*' @{tok = TK_ArrowStar;}; dot_star = '.*' @{tok = TK_DotStar;}; # Three char compounds, first item already buffered. */ dot_dot_dot = '...' @{tok = TK_DotDotDot;}; # All compunds compound = namesep | deqs | neqs | and_and | or_or | mult_assign | div_assign | percent_assign | plus_assign | minus_assign | amp_assign | caret_assign | bar_assign | plus_plus | minus_minus | arrow | arrow_star | dot_star | dot_dot_dot; # Single char symbols. symbol = ( punct - [_"'] ) @{tok = fc;}; action discard { discard = true; } # Comments and whitespace. commc = '/*' @discard ( any* $0 '*/' @1 ) @{tok = TK_Comment;}; commcc = '//' @discard ( any* $0 '\n' @1 ) @{tok = TK_Comment;}; whitespace = ( any - 33..126 )+ >discard @{tok = TK_Whitespace;}; # All outside code tokens. tokens = ( id | slit | dlit | float | integer_decimal | integer_octal | integer_hex | compound | symbol | commc | commcc | whitespace ); action onError { if ( tok != 0 ) { const char *rst_data; if ( tok == TK_Comment || tok == TK_Whitespace ) { /* Reset comment status, don't send. */ discard = false; /* Restart right at the error point if consuming whitespace or * a comment. Consume may have spanned multiple buffers. */ rst_data = fpc; } else { /* Send the token. */ token( ts, te - ts + 1 ); /* Restart right after the token. */ rst_data = te+1; } ts = 0; fexec rst_data; fgoto main; } } main := tokens >{ts=fpc;} @{te=fpc;} $!onError; }%% %% write data; int Scanner::init( ) { tok = 0; ts = 0; te = 0; %% write init; return 1; } int Scanner::execute( const char *data, int len ) { const char *p = data; const char *pe = data + len; const char *eof = pe; %% write exec; if ( cs == Scanner_error ) return -1; if ( cs >= Scanner_first_final ) return 1; return 0; } int Scanner::finish( ) { if ( cs == Scanner_error ) return -1; if ( cs >= Scanner_first_final ) return 1; return 0; } void token( const char *data, int len ) { cout << "<" << tok << "> "; for ( int i = 0; i < len; i++ ) cout << data[i]; cout << '\n'; } void test( const char * data ) { Scanner scanner; scanner.init(); scanner.execute( data, strlen(data) ); scanner.finish(); if ( tok != 0 && tok != TK_Comment && tok != TK_Whitespace ) token( ts, te - ts + 1 ); } int main() { test( "/*\n" " * Copyright \n" " */\n" "\n" "\n" "/* Move ranges to the singles list. */\n" "void RedFsmAp::move( RedStateAp *state )\n" "{\n" " RedTranst &range = state->outRange;\n" " for ( int rpos = 0; rpos < range.length(); ) {\n" " if ( can( range, rpos ) ) {\n" " while ( range[rpos].value != range[rpos+1].value ) {\n" " single.append( range[rpos+1] );\n" " }\n" " \n" " range[rpos].highKey = range[rpos+1].highKey;\n" " }\n" " else if ( keyOps->span( range[rpos].lowKey, range[rpos].highKey ) == 1 ) {\n" " single.append( range[rpos] );\n" " }\n" " }\n" "}\n" "\n" ); test( "->*\n" ".*\n" "/*\"*/\n" "\"/*\"\n" "L'\"'\n" "L\"'\"\n" "...\n" ); } #ifdef _____OUTPUT_____ <195> void <195> RedFsmAp <197> :: <195> move <40> ( <195> RedStateAp <42> * <195> state <41> ) <123> { <195> RedTranst <38> & <195> range <61> = <195> state <211> -> <195> outRange <59> ; <195> for <40> ( <195> int <195> rpos <61> = <218> 0 <59> ; <195> rpos <60> < <195> range <46> . <195> length <40> ( <41> ) <59> ; <41> ) <123> { <195> if <40> ( <195> can <40> ( <195> range <44> , <195> rpos <41> ) <41> ) <123> { <195> while <40> ( <195> range <91> [ <195> rpos <93> ] <46> . <195> value <224> != <195> range <91> [ <195> rpos <43> + <218> 1 <93> ] <46> . <195> value <41> ) <123> { <195> single <46> . <195> append <40> ( <195> range <91> [ <195> rpos <43> + <218> 1 <93> ] <41> ) <59> ; <125> } <195> range <91> [ <195> rpos <93> ] <46> . <195> highKey <61> = <195> range <91> [ <195> rpos <43> + <218> 1 <93> ] <46> . <195> highKey <59> ; <125> } <195> else <195> if <40> ( <195> keyOps <211> -> <195> span <40> ( <195> range <91> [ <195> rpos <93> ] <46> . <195> lowKey <44> , <195> range <91> [ <195> rpos <93> ] <46> . <195> highKey <41> ) <223> == <218> 1 <41> ) <123> { <195> single <46> . <195> append <40> ( <195> range <91> [ <195> rpos <93> ] <41> ) <59> ; <125> } <125> } <125> } <214> ->* <215> .* <192> "/*" <193> L'"' <192> L"'" <240> ... #endif ragel-6.10/ragel.vim0000664000175000017500000001341113065111230011254 00000000000000" Vim syntax file " " Language: Ragel " Author: Adrian Thurston syntax clear " " Outside code " " Comments syntax region ocComment start="\/\*" end="\*\/" syntax match ocComment "\/\/.*$" " Anything preprocessor syntax match ocPreproc "#\(.\|\\\n\)*$" syntax region ocPreproc start="#" end="[^\\]$" " Strings syntax match ocLiteral "'\(\\.\|[^'\\]\)*'" syntax match ocLiteral "\"\(\\.\|[^\"\\]\)*\"" " C/C++ Keywords syntax keyword ocType unsigned signed void char short int long float double bool syntax keyword ocType inline static extern register const volatile auto syntax keyword ocType union enum struct class typedef syntax keyword ocType namespace template typename mutable syntax keyword ocKeyword break continue default do else for syntax keyword ocKeyword goto if return switch while syntax keyword ocKeyword new delete this using friend public private protected sizeof syntax keyword ocKeyword throw try catch operator typeid syntax keyword ocKeyword and bitor xor compl bitand and_eq or_eq xor_eq not not_eq syntax keyword ocKeyword static_cast dynamic_cast " Numbers syntax match ocNumber "[0-9][0-9]*[Ll]\?[Ll]\?" syntax match ocNumber "0x[0-9a-fA-F][0-9a-fA-F]*" " Booleans syntax keyword ocBoolean true false " Identifiers syntax match anyId "[a-zA-Z_][a-zA-Z_0-9]*" " Inline code only syntax keyword fsmType fpc fc fcurs fbuf fblen ftargs fstack syntax keyword fsmKeyword fhold fgoto fcall fret fentry fnext fexec fbreak syntax cluster rlItems contains=rlComment,rlLiteral,rlAugmentOps,rlOtherOps,rlKeywords,rlWrite,rlCodeCurly,rlCodeSemi,rlNumber,anyId,rlLabelColon,rlExprKeywords,rlBuiltIns syntax region machineSpec1 matchgroup=beginRL start="%%{" end="}%%" contains=@rlItems syntax region machineSpec2 matchgroup=beginRL start="%%[^{]"rs=e-1 end="$" keepend contains=@rlItems syntax region machineSpec2 matchgroup=beginRL start="%%$" end="$" keepend contains=@rlItems " Comments syntax match rlComment "#.*$" contained " Literals syntax match rlLiteral "'\(\\.\|[^'\\]\)*'[i]*" contained syntax match rlLiteral "\"\(\\.\|[^\"\\]\)*\"[i]*" contained syntax match rlLiteral /\/\(\\.\|[^\/\\]\)*\/[i]*/ contained syntax match rlLiteral "\[\(\\.\|[^\]\\]\)*\]" contained " Numbers syntax match rlNumber "[0-9][0-9]*" contained syntax match rlNumber "0x[0-9a-fA-F][0-9a-fA-F]*" contained " Operators syntax match rlAugmentOps "[>$%@]" contained syntax match rlAugmentOps "<>\|<" contained syntax match rlAugmentOps "[>\<$%@][!\^/*~]" contained syntax match rlAugmentOps "[>$%]?" contained syntax match rlAugmentOps "<>[!\^/*~]" contained syntax match rlAugmentOps "=>" contained syntax match rlOtherOps "->" contained syntax match rlOtherOps ":>" contained syntax match rlOtherOps ":>>" contained syntax match rlOtherOps "<:" contained " Keywords " FIXME: Enable the range keyword post 5.17. " syntax keyword rlKeywords machine action context include range contained syntax keyword rlKeywords machine action context include import export prepush postpop contained syntax keyword rlExprKeywords when inwhen outwhen err lerr eof from to contained " Built-in rules syntax keyword rlBuiltIns any ascii extend alpha digit alnum lower upper xdigit cntrl graph print punct space zlen empty contained " Case Labels syntax keyword caseLabelKeyword case contained syntax cluster caseLabelItems contains=ocComment,ocPreproc,ocLiteral,ocType,ocKeyword,caseLabelKeyword,ocNumber,ocBoolean,anyId,fsmType,fsmKeyword syntax match caseLabelColon "case" contains=@caseLabelItems syntax match caseLabelColon "case[\t ]\+.*:$" contains=@caseLabelItems syntax match caseLabelColon "case[\t ]\+.*:[^=:]"me=e-1 contains=@caseLabelItems " Labels syntax match ocLabelColon "^[\t ]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:$" contains=anyLabel syntax match ocLabelColon "^[\t ]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:[^=:]"me=e-1 contains=anyLabel syntax match rlLabelColon "[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:$" contained contains=anyLabel syntax match rlLabelColon "[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:[^=:>]"me=e-1 contained contains=anyLabel syntax match anyLabel "[a-zA-Z_][a-zA-Z_0-9]*" contained " All items that can go in a code block. syntax cluster inlineItems contains=rlCodeCurly,ocComment,ocPreproc,ocLiteral,ocType,ocKeyword,ocNumber,ocBoolean,ocLabelColon,anyId,fsmType,fsmKeyword,caseLabelColon " Blocks of code. rlCodeCurly is recursive. syntax region rlCodeCurly matchgroup=NONE start="{" end="}" contained contains=@inlineItems syntax region rlCodeSemi matchgroup=Type start="\" start="\" start="\" start="\" matchgroup=NONE end=";" contained contains=@inlineItems syntax region rlWrite matchgroup=Type start="\" matchgroup=NONE end="[;)]" contained contains=rlWriteKeywords,rlWriteOptions syntax keyword rlWriteKeywords init data exec exports start error first_final contained syntax keyword rlWriteOptions noerror nofinal noentry noprefix noend nocs contained " " Sync at the start of machine specs. " " Match The ragel delimiters only if there quotes no ahead on the same line. " On the open marker, use & to consume the leader. syntax sync match ragelSyncPat grouphere NONE "^[^\'\"%]*%%{&^[^\'\"%]*" syntax sync match ragelSyncPat grouphere NONE "^[^\'\"%]*%%[^{]&^[^\'\"%]*" syntax sync match ragelSyncPat grouphere NONE "^[^\'\"]*}%%" " " Specifying Groups " hi link ocComment Comment hi link ocPreproc Macro hi link ocLiteral String hi link ocType Type hi link ocKeyword Keyword hi link ocNumber Number hi link ocBoolean Boolean hi link rlComment Comment hi link rlNumber Number hi link rlLiteral String hi link rlAugmentOps Keyword hi link rlExprKeywords Keyword hi link rlWriteKeywords Keyword hi link rlWriteOptions Keyword hi link rlKeywords Type hi link fsmType Type hi link fsmKeyword Keyword hi link anyLabel Label hi link caseLabelKeyword Keyword hi link beginRL Type hi link rlBuiltIns Constant let b:current_syntax = "ragel" ragel-6.10/ragel/0000775000175000017500000000000013065122770010632 500000000000000ragel-6.10/ragel/cdtable.cpp0000664000175000017500000006575613065111230012664 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdtable.h" #include "redfsm.h" #include "gendata.h" /* Determine if we should use indicies or not. */ void TabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &TabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &TabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &TabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &TabCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &TabCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &TabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &TabCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, true, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &TabCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &TabCodeGen::COND_OFFSETS() { out << "\t"; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the key offset ahead. */ curKeyOffset += st->stateCondList.length(); } out << "\n"; return out; } std::ostream &TabCodeGen::KEY_OFFSETS() { out << "\t"; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the key offset ahead. */ curKeyOffset += st->outSingle.length() + st->outRange.length()*2; } out << "\n"; return out; } std::ostream &TabCodeGen::INDEX_OFFSETS() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ curIndOffset += st->outSingle.length() + st->outRange.length(); if ( st->defTrans != 0 ) curIndOffset += 1; } out << "\n"; return out; } std::ostream &TabCodeGen::COND_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->stateCondList.length(); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::SINGLE_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->outSingle.length(); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::RANGE_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit length of range index. */ out << st->outRange.length(); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::TO_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::FROM_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::EOF_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::EOF_TRANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &TabCodeGen::COND_KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Lower key. */ out << KEY( sc->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << KEY( sc->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &TabCodeGen::COND_SPACES() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Cond Space id. */ out << sc->condSpace->condSpaceId << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &TabCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << KEY( stel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ out << KEY( rtel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << KEY( rtel->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &TabCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << stel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { out << rtel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { out << st->defTrans->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &TabCodeGen::TRANS_TARGS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Add any eof transitions that have not yet been written out above. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &TabCodeGen::TRANS_ACTIONS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Add any eof transitions that have not yet been written out above. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &TabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } std::ostream &TabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } void TabCodeGen::LOCATE_TRANS() { out << " _keys = " << ARR_OFF( K(), KO() + "[" + vCS() + "]" ) << ";\n" " _trans = " << IO() << "[" << vCS() << "];\n" "\n" " _klen = " << SL() << "[" << vCS() << "];\n" " if ( _klen > 0 ) {\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_lower = _keys;\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_mid;\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_upper = _keys + _klen - 1;\n" " while (1) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = _lower + ((_upper-_lower) >> 1);\n" " if ( " << GET_WIDE_KEY() << " < *_mid )\n" " _upper = _mid - 1;\n" " else if ( " << GET_WIDE_KEY() << " > *_mid )\n" " _lower = _mid + 1;\n" " else {\n" " _trans += " << CAST(UINT()) << "(_mid - _keys);\n" " goto _match;\n" " }\n" " }\n" " _keys += _klen;\n" " _trans += _klen;\n" " }\n" "\n" " _klen = " << RL() << "[" << vCS() << "];\n" " if ( _klen > 0 ) {\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_lower = _keys;\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_mid;\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_upper = _keys + (_klen<<1) - 2;\n" " while (1) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = _lower + (((_upper-_lower) >> 1) & ~1);\n" " if ( " << GET_WIDE_KEY() << " < _mid[0] )\n" " _upper = _mid - 2;\n" " else if ( " << GET_WIDE_KEY() << " > _mid[1] )\n" " _lower = _mid + 2;\n" " else {\n" " _trans += " << CAST(UINT()) << "((_mid - _keys)>>1);\n" " goto _match;\n" " }\n" " }\n" " _trans += _klen;\n" " }\n" "\n"; } void TabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{"; ret << vCS() << " = " << gotoDest << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void TabCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{"; ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << "); "; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void TabCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void TabCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void TabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void TabCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; } void TabCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void TabCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish, false ); ret << ");"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void TabCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "]; "; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false, false ); ret << "}"; } if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void TabCodeGen::BREAK( ostream &ret, int targState, bool csForced ) { outLabelUsed = true; ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }"; } void TabCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void TabCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << ";\n" " _klen = " << CL() << "[" << vCS() << "];\n" " _keys = " << ARR_OFF( CK(), "(" + CO() + "[" + vCS() + "]*2)" ) << ";\n" " if ( _klen > 0 ) {\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_lower = _keys;\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_mid;\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_upper = _keys + (_klen<<1) - 2;\n" " while (1) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = _lower + (((_upper-_lower) >> 1) & ~1);\n" " if ( " << GET_WIDE_KEY() << " < _mid[0] )\n" " _upper = _mid - 2;\n" " else if ( " << GET_WIDE_KEY() << " > _mid[1] )\n" " _lower = _mid + 2;\n" " else {\n" " switch ( " << C() << "[" << CO() << "[" << vCS() << "]" " + ((_mid - _keys)>>1)] ) {\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId << ": {\n"; out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } out << " break;\n" " }\n"; } SWITCH_DEFAULT(); out << " }\n" " break;\n" " }\n" " }\n" " }\n" "\n"; } void TabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n" " int _klen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n" " " << UINT() << " _trans;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "_acts;\n" " " << UINT() << " _nacts;\n"; } out << " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_keys;\n" "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << ARR_OFF( A(), FSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); out << "_match:\n"; if ( useIndicies ) out << " _trans = " << I() << "[_trans];\n"; if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " _acts = " << ARR_OFF( A(), TA() + "[_trans]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 )\n {\n" " switch ( *_acts++ )\n {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << ARR_OFF( A(), TSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "__acts = " << ARR_OFF( A(), EA() + "[" + vCS() + "]" ) << ";\n" " " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n" " while ( __nacts-- > 0 ) {\n" " switch ( *__acts++ ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/mlfflat.h0000664000175000017500000000316613065111230012343 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MLFFLAT_H #define _MLFFLAT_H #include #include "mlflat.h" /* Forwards. */ //struct CodeGenData; /* * OCamlFFlatCodeGen */ class OCamlFFlatCodeGen : public OCamlFlatCodeGen { public: OCamlFFlatCodeGen( ostream &out ) : OCamlFlatCodeGen(out) {} private: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/rlscan.h0000664000175000017500000000703613065111230012200 00000000000000/* * Copyright 2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RLSCAN_H #define _RLSCAN_H #include #include "rlscan.h" #include "vector.h" #include "rlparse.h" #include "parsedata.h" #include "avltree.h" #include "vector.h" using std::istream; using std::ostream; extern char *Parser_lelNames[]; struct Scanner { Scanner( InputData &id, const char *fileName, istream &input, Parser *inclToParser, char *inclSectionTarg, int includeDepth, bool importMachines ) : id(id), fileName(fileName), input(input), inclToParser(inclToParser), inclSectionTarg(inclSectionTarg), includeDepth(includeDepth), importMachines(importMachines), cur_token(0), line(1), column(1), lastnl(0), parser(0), ignoreSection(false), parserExistsError(false), whitespaceOn(true), lastToken(0) {} bool duplicateInclude( char *inclFileName, char *inclSectionName ); /* Make a list of places to look for an included file. */ char **makeIncludePathChecks( const char *curFileName, const char *fileName, int len ); std::ifstream *tryOpenInclude( char **pathChecks, long &found ); void handleMachine(); void handleInclude(); void handleImport(); void init(); void token( int type, char *start, char *end ); void token( int type, char c ); void token( int type ); void processToken( int type, char *tokdata, int toklen ); void directToParser( Parser *toParser, const char *tokFileName, int tokLine, int tokColumn, int type, char *tokdata, int toklen ); void flushImport( ); void importToken( int type, char *start, char *end ); void pass( int token, char *start, char *end ); void pass(); void updateCol(); void startSection(); void endSection(); void do_scan(); bool active(); ostream &scan_error(); InputData &id; const char *fileName; istream &input; Parser *inclToParser; char *inclSectionTarg; int includeDepth; bool importMachines; /* For import parsing. */ int tok_cs, tok_act; int *tok_ts, *tok_te; int cur_token; static const int max_tokens = 32; int token_data[max_tokens]; char *token_strings[max_tokens]; int token_lens[max_tokens]; /* For section processing. */ int cs; char *word, *lit; int word_len, lit_len; /* For character scanning. */ int line; InputLoc sectionLoc; char *ts, *te; int column; char *lastnl; /* Set by machine statements, these persist from section to section * allowing for unnamed sections. */ Parser *parser; bool ignoreSection; /* This is set if ragel has already emitted an error stating that * no section name has been seen and thus no parser exists. */ bool parserExistsError; /* This is for inline code. By default it is on. It goes off for * statements and values in inline blocks which are parsed. */ bool whitespaceOn; /* Keeps a record of the previous token sent to the section parser. */ int lastToken; }; #endif ragel-6.10/ragel/buffer.h0000664000175000017500000000254613065111230012170 00000000000000/* * Copyright 2003 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _BUFFER_H #define _BUFFER_H #define BUFFER_INITIAL_SIZE 4096 /* An automatically grown buffer for collecting tokens. Always reuses space; * never down resizes. */ struct Buffer { Buffer() { data = (char*) malloc( BUFFER_INITIAL_SIZE ); allocated = BUFFER_INITIAL_SIZE; length = 0; } ~Buffer() { free(data); } void append( char p ) { if ( length == allocated ) { allocated *= 2; data = (char*) realloc( data, allocated ); } data[length++] = p; } void clear() { length = 0; } char *data; int allocated; int length; }; #endif ragel-6.10/ragel/redfsm.cpp0000664000175000017500000004052513065111230012531 00000000000000/* * Copyright 2001-2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "redfsm.h" #include "avlmap.h" #include "mergesort.h" #include #include using std::ostringstream; string GenAction::nameOrLoc() { if ( name != 0 ) return string(name); else { ostringstream ret; ret << loc.line << ":" << loc.col; return ret.str(); } } RedFsmAp::RedFsmAp() : forcedErrorState(false), nextActionId(0), nextTransId(0), startState(0), errState(0), errTrans(0), firstFinState(0), numFinStates(0), bAnyToStateActions(false), bAnyFromStateActions(false), bAnyRegActions(false), bAnyEofActions(false), bAnyEofTrans(false), bAnyActionGotos(false), bAnyActionCalls(false), bAnyActionRets(false), bAnyActionByValControl(false), bAnyRegActionRets(false), bAnyRegActionByValControl(false), bAnyRegNextStmt(false), bAnyRegCurStateRef(false), bAnyRegBreak(false), bAnyConditions(false) { } /* Does the machine have any actions. */ bool RedFsmAp::anyActions() { return actionMap.length() > 0; } void RedFsmAp::depthFirstOrdering( RedStateAp *state ) { /* Nothing to do if the state is already on the list. */ if ( state->onStateList ) return; /* Doing depth first, put state on the list. */ state->onStateList = true; stateList.append( state ); /* At this point transitions should only be in ranges. */ assert( state->outSingle.length() == 0 ); assert( state->defTrans == 0 ); /* Recurse on everything ranges. */ for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->targ != 0 ) depthFirstOrdering( rtel->value->targ ); } } /* Ordering states by transition connections. */ void RedFsmAp::depthFirstOrdering() { /* Init on state list flags. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) st->onStateList = false; /* Clear out the state list, we will rebuild it. */ int stateListLen = stateList.length(); stateList.abandon(); /* Add back to the state list from the start state and all other entry * points. */ if ( startState != 0 ) depthFirstOrdering( startState ); for ( RedStateSet::Iter en = entryPoints; en.lte(); en++ ) depthFirstOrdering( *en ); if ( forcedErrorState ) depthFirstOrdering( errState ); /* Make sure we put everything back on. */ assert( stateListLen == stateList.length() ); } /* Assign state ids by appearance in the state list. */ void RedFsmAp::sequentialStateIds() { /* Table based machines depend on the state numbers starting at zero. */ nextStateId = 0; for ( RedStateList::Iter st = stateList; st.lte(); st++ ) st->id = nextStateId++; } /* Stable sort the states by final state status. */ void RedFsmAp::sortStatesByFinal() { /* Move forward through the list and throw final states onto the end. */ RedStateAp *state = 0; RedStateAp *next = stateList.head; RedStateAp *last = stateList.tail; while ( state != last ) { /* Move forward and load up the next. */ state = next; next = state->next; /* Throw to the end? */ if ( state->isFinal ) { stateList.detach( state ); stateList.append( state ); } } } /* Assign state ids by final state state status. */ void RedFsmAp::sortStateIdsByFinal() { /* Table based machines depend on this starting at zero. */ nextStateId = 0; /* First pass to assign non final ids. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { if ( ! st->isFinal ) st->id = nextStateId++; } /* Second pass to assign final ids. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { if ( st->isFinal ) st->id = nextStateId++; } } struct CmpStateById { static int compare( RedStateAp *st1, RedStateAp *st2 ) { if ( st1->id < st2->id ) return -1; else if ( st1->id > st2->id ) return 1; else return 0; } }; void RedFsmAp::sortByStateId() { /* Make the array. */ int pos = 0; RedStateAp **ptrList = new RedStateAp*[stateList.length()]; for ( RedStateList::Iter st = stateList; st.lte(); st++, pos++ ) ptrList[pos] = st; MergeSort mergeSort; mergeSort.sort( ptrList, stateList.length() ); stateList.abandon(); for ( int st = 0; st < pos; st++ ) stateList.append( ptrList[st] ); delete[] ptrList; } /* Find the final state with the lowest id. */ void RedFsmAp::findFirstFinState() { for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { if ( st->isFinal && (firstFinState == 0 || st->id < firstFinState->id) ) firstFinState = st; } } void RedFsmAp::assignActionLocs() { int nextLocation = 0; for ( GenActionTableMap::Iter act = actionMap; act.lte(); act++ ) { /* Store the loc, skip over the array and a null terminator. */ act->location = nextLocation; nextLocation += act->key.length() + 1; } } /* Check if we can extend the current range by displacing any ranges * ahead to the singles. */ bool RedFsmAp::canExtend( const RedTransList &list, int pos ) { /* Get the transition that we want to extend. */ RedTransAp *extendTrans = list[pos].value; /* Look ahead in the transition list. */ for ( int next = pos + 1; next < list.length(); pos++, next++ ) { /* If they are not continuous then cannot extend. */ Key nextKey = list[next].lowKey; nextKey.decrement(); if ( list[pos].highKey != nextKey ) break; /* Check for the extenstion property. */ if ( extendTrans == list[next].value ) return true; /* If the span of the next element is more than one, then don't keep * checking, it won't be moved to single. */ unsigned long long nextSpan = keyOps->span( list[next].lowKey, list[next].highKey ); if ( nextSpan > 1 ) break; } return false; } /* Move ranges to the singles list. */ void RedFsmAp::moveTransToSingle( RedStateAp *state ) { RedTransList &range = state->outRange; RedTransList &single = state->outSingle; for ( int rpos = 0; rpos < range.length(); ) { /* Check if this is a range we can extend. */ if ( canExtend( range, rpos ) ) { /* Transfer singles over. */ while ( range[rpos].value != range[rpos+1].value ) { /* Transfer the range to single. */ single.append( range[rpos+1] ); range.remove( rpos+1 ); } /* Extend. */ range[rpos].highKey = range[rpos+1].highKey; range.remove( rpos+1 ); } /* Maybe move it to the singles. */ else if ( keyOps->span( range[rpos].lowKey, range[rpos].highKey ) == 1 ) { single.append( range[rpos] ); range.remove( rpos ); } else { /* Keeping it in the ranges. */ rpos += 1; } } } /* Look through ranges and choose suitable single character transitions. */ void RedFsmAp::chooseSingle() { /* Loop the states. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { /* Rewrite the transition list taking out the suitable single * transtions. */ moveTransToSingle( st ); } } void RedFsmAp::makeFlat() { for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { if ( st->stateCondList.length() == 0 ) { st->condLowKey = 0; st->condHighKey = 0; } else { st->condLowKey = st->stateCondList.head->lowKey; st->condHighKey = st->stateCondList.tail->highKey; unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); st->condList = new GenCondSpace*[ span ]; memset( st->condList, 0, sizeof(GenCondSpace*)*span ); for ( GenStateCondList::Iter sci = st->stateCondList; sci.lte(); sci++ ) { unsigned long long base, trSpan; base = keyOps->span( st->condLowKey, sci->lowKey )-1; trSpan = keyOps->span( sci->lowKey, sci->highKey ); for ( unsigned long long pos = 0; pos < trSpan; pos++ ) st->condList[base+pos] = sci->condSpace; } } if ( st->outRange.length() == 0 ) { st->lowKey = st->highKey = 0; st->transList = 0; } else { st->lowKey = st->outRange[0].lowKey; st->highKey = st->outRange[st->outRange.length()-1].highKey; unsigned long long span = keyOps->span( st->lowKey, st->highKey ); st->transList = new RedTransAp*[ span ]; memset( st->transList, 0, sizeof(RedTransAp*)*span ); for ( RedTransList::Iter trans = st->outRange; trans.lte(); trans++ ) { unsigned long long base, trSpan; base = keyOps->span( st->lowKey, trans->lowKey )-1; trSpan = keyOps->span( trans->lowKey, trans->highKey ); for ( unsigned long long pos = 0; pos < trSpan; pos++ ) st->transList[base+pos] = trans->value; } /* Fill in the gaps with the default transition. */ for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->transList[pos] == 0 ) st->transList[pos] = st->defTrans; } } } } /* A default transition has been picked, move it from the outRange to the * default pointer. */ void RedFsmAp::moveToDefault( RedTransAp *defTrans, RedStateAp *state ) { /* Rewrite the outRange, omitting any ranges that use * the picked default. */ RedTransList outRange; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { /* If it does not take the default, copy it over. */ if ( rtel->value != defTrans ) outRange.append( *rtel ); } /* Save off the range we just created into the state's range. */ state->outRange.transfer( outRange ); /* Store the default. */ state->defTrans = defTrans; } bool RedFsmAp::alphabetCovered( RedTransList &outRange ) { /* Cannot cover without any out ranges. */ if ( outRange.length() == 0 ) return false; /* If the first range doesn't start at the the lower bound then the * alphabet is not covered. */ RedTransList::Iter rtel = outRange; if ( keyOps->minKey < rtel->lowKey ) return false; /* Check that every range is next to the previous one. */ rtel.increment(); for ( ; rtel.lte(); rtel++ ) { Key highKey = rtel[-1].highKey; highKey.increment(); if ( highKey != rtel->lowKey ) return false; } /* The last must extend to the upper bound. */ RedTransEl *last = &outRange[outRange.length()-1]; if ( last->highKey < keyOps->maxKey ) return false; return true; } RedTransAp *RedFsmAp::chooseDefaultSpan( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ RedTransSet stateTransSet; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) stateTransSet.insert( rtel->value ); /* For each transition in the find how many alphabet characters the * transition spans. */ unsigned long long *span = new unsigned long long[stateTransSet.length()]; memset( span, 0, sizeof(unsigned long long) * stateTransSet.length() ); for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { /* Lookup the transition in the set. */ RedTransAp **inSet = stateTransSet.find( rtel->value ); int pos = inSet - stateTransSet.data; span[pos] += keyOps->span( rtel->lowKey, rtel->highKey ); } /* Find the max span, choose it for making the default. */ RedTransAp *maxTrans = 0; unsigned long long maxSpan = 0; for ( RedTransSet::Iter rtel = stateTransSet; rtel.lte(); rtel++ ) { if ( span[rtel.pos()] > maxSpan ) { maxSpan = span[rtel.pos()]; maxTrans = *rtel; } } delete[] span; return maxTrans; } /* Pick default transitions from ranges for the states. */ void RedFsmAp::chooseDefaultSpan() { /* Loop the states. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { /* Only pick a default transition if the alphabet is covered. This * avoids any transitions in the out range that go to error and avoids * the need for an ERR state. */ if ( alphabetCovered( st->outRange ) ) { /* Pick a default transition by largest span. */ RedTransAp *defTrans = chooseDefaultSpan( st ); /* Rewrite the transition list taking out the transition we picked * as the default and store the default. */ moveToDefault( defTrans, st ); } } } RedTransAp *RedFsmAp::chooseDefaultGoto( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ RedTransSet stateTransSet; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->targ == state->next ) return rtel->value; } return 0; } void RedFsmAp::chooseDefaultGoto() { /* Loop the states. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { /* Pick a default transition. */ RedTransAp *defTrans = chooseDefaultGoto( st ); if ( defTrans == 0 ) defTrans = chooseDefaultSpan( st ); /* Rewrite the transition list taking out the transition we picked * as the default and store the default. */ moveToDefault( defTrans, st ); } } RedTransAp *RedFsmAp::chooseDefaultNumRanges( RedStateAp *state ) { /* Make a set of transitions from the outRange. */ RedTransSet stateTransSet; for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) stateTransSet.insert( rtel->value ); /* For each transition in the find how many ranges use the transition. */ int *numRanges = new int[stateTransSet.length()]; memset( numRanges, 0, sizeof(int) * stateTransSet.length() ); for ( RedTransList::Iter rtel = state->outRange; rtel.lte(); rtel++ ) { /* Lookup the transition in the set. */ RedTransAp **inSet = stateTransSet.find( rtel->value ); numRanges[inSet - stateTransSet.data] += 1; } /* Find the max number of ranges. */ RedTransAp *maxTrans = 0; int maxNumRanges = 0; for ( RedTransSet::Iter rtel = stateTransSet; rtel.lte(); rtel++ ) { if ( numRanges[rtel.pos()] > maxNumRanges ) { maxNumRanges = numRanges[rtel.pos()]; maxTrans = *rtel; } } delete[] numRanges; return maxTrans; } void RedFsmAp::chooseDefaultNumRanges() { /* Loop the states. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { /* Pick a default transition. */ RedTransAp *defTrans = chooseDefaultNumRanges( st ); /* Rewrite the transition list taking out the transition we picked * as the default and store the default. */ moveToDefault( defTrans, st ); } } RedTransAp *RedFsmAp::getErrorTrans( ) { /* If the error trans has not been made aready, make it. */ if ( errTrans == 0 ) { /* This insert should always succeed since no transition created by * the user can point to the error state. */ errTrans = new RedTransAp( getErrorState(), 0, nextTransId++ ); RedTransAp *inRes = transSet.insert( errTrans ); assert( inRes != 0 ); } return errTrans; } RedStateAp *RedFsmAp::getErrorState() { /* Something went wrong. An error state is needed but one was not supplied * by the frontend. */ assert( errState != 0 ); return errState; } RedTransAp *RedFsmAp::allocateTrans( RedStateAp *targ, RedAction *action ) { /* Create a reduced trans and look for it in the transiton set. */ RedTransAp redTrans( targ, action, 0 ); RedTransAp *inDict = transSet.find( &redTrans ); if ( inDict == 0 ) { inDict = new RedTransAp( targ, action, nextTransId++ ); transSet.insert( inDict ); } return inDict; } void RedFsmAp::partitionFsm( int nparts ) { /* At this point the states are ordered by a depth-first traversal. We * will allocate to partitions based on this ordering. */ this->nParts = nparts; int partSize = stateList.length() / nparts; int remainder = stateList.length() % nparts; int numInPart = partSize; int partition = 0; if ( remainder-- > 0 ) numInPart += 1; for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { st->partition = partition; numInPart -= 1; if ( numInPart == 0 ) { partition += 1; numInPart = partSize; if ( remainder-- > 0 ) numInPart += 1; } } } void RedFsmAp::setInTrans() { /* First pass counts the number of transitions. */ for ( TransApSet::Iter trans = transSet; trans.lte(); trans++ ) trans->targ->numInTrans += 1; /* Pass over states to allocate the needed memory. Reset the counts so we * can use them as the current size. */ for ( RedStateList::Iter st = stateList; st.lte(); st++ ) { st->inTrans = new RedTransAp*[st->numInTrans]; st->numInTrans = 0; } /* Second pass over transitions copies pointers into the in trans list. */ for ( TransApSet::Iter trans = transSet; trans.lte(); trans++ ) trans->targ->inTrans[trans->targ->numInTrans++] = trans; } ragel-6.10/ragel/rubycodegen.h0000664000175000017500000001331013065111230013214 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RUBY_CODEGEN_H #define _RUBY_CODEGEN_H #include "common.h" #include "gendata.h" /* Integer array line length. */ #define IALL 8 class RubyCodeGen : public CodeGenData { public: RubyCodeGen( ostream &out ) : CodeGenData(out) { } virtual ~RubyCodeGen() {} protected: ostream &START_ARRAY_LINE(); ostream &ARRAY_ITEM( string item, int count, bool last ); ostream &END_ARRAY_LINE(); string FSM_NAME(); string START_STATE_ID(); string ERROR_STATE(); string FIRST_FINAL_STATE(); void INLINE_LIST(ostream &ret, GenInlineList *inlineList, int targState, bool inFinish); string ACCESS(); void ACTION( ostream &ret, GenAction *action, int targState, bool inFinish ); string GET_KEY(); string GET_WIDE_KEY(); string GET_WIDE_KEY( RedStateAp *state ); string KEY( Key key ); string TABS( int level ); string INT( int i ); void CONDITION( ostream &ret, GenAction *condition ); string ALPH_TYPE(); string WIDE_ALPH_TYPE(); string ARRAY_TYPE( unsigned long maxVal ); ostream &ACTIONS_ARRAY(); void STATE_IDS(); string DATA_PREFIX(); string PM() { return "_" + DATA_PREFIX() + "partition_map"; } string C() { return "_" + DATA_PREFIX() + "cond_spaces"; } string CK() { return "_" + DATA_PREFIX() + "cond_keys"; } string K() { return "_" + DATA_PREFIX() + "trans_keys"; } string I() { return "_" + DATA_PREFIX() + "indicies"; } string CO() { return "_" + DATA_PREFIX() + "cond_offsets"; } string KO() { return "_" + DATA_PREFIX() + "key_offsets"; } string IO() { return "_" + DATA_PREFIX() + "index_offsets"; } string CL() { return "_" + DATA_PREFIX() + "cond_lengths"; } string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } string ET() { return "_" + DATA_PREFIX() + "eof_trans"; } string SP() { return "_" + DATA_PREFIX() + "key_spans"; } string CSP() { return "_" + DATA_PREFIX() + "cond_key_spans"; } string START() { return DATA_PREFIX() + "start"; } string ERROR() { return DATA_PREFIX() + "error"; } string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; } string CTXDATA() { return DATA_PREFIX() + "ctxdata"; } public: string NULL_ITEM(); ostream &OPEN_ARRAY( string type, string name ); ostream &CLOSE_ARRAY(); ostream &STATIC_VAR( string type, string name ); string ARR_OFF( string ptr, string offset ); string P(); string PE(); string vEOF(); string vCS(); string TOP(); string STACK(); string ACT(); string TOKSTART(); string TOKEND(); string DATA(); void finishRagelDef(); unsigned int arrayTypeSize( unsigned long maxVal ); protected: virtual void writeExports(); virtual void writeInit(); virtual void writeStart(); virtual void writeFirstFinal(); virtual void writeError(); /* Determine if we should use indicies. */ virtual void calcIndexSize(); virtual void BREAK( ostream &ret, int targState ) = 0; virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ) = 0; virtual void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ) = 0; virtual void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) = 0; virtual void RET( ostream &ret, bool inFinish ) = 0; virtual void NEXT( ostream &ret, int nextDest, bool inFinish ) = 0; virtual void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; virtual int TO_STATE_ACTION( RedStateAp *state ) = 0; virtual int FROM_STATE_ACTION( RedStateAp *state ) = 0; virtual int EOF_ACTION( RedStateAp *state ) = 0; virtual int TRANS_ACTION( RedTransAp *trans ); void EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void SET_ACT( ostream &ret, GenInlineItem *item ); void INIT_TOKSTART( ostream &ret, GenInlineItem *item ); void INIT_ACT( ostream &ret, GenInlineItem *item ); void SET_TOKSTART( ostream &ret, GenInlineItem *item ); void SET_TOKEND( ostream &ret, GenInlineItem *item ); void GET_TOKEND( ostream &ret, GenInlineItem *item ); void SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish ); protected: ostream &source_warning(const InputLoc &loc); ostream &source_error(const InputLoc &loc); /* fields */ bool outLabelUsed; bool againLabelUsed; bool useIndicies; void genLineDirective( ostream &out ); }; /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ #endif ragel-6.10/ragel/cstable.cpp0000664000175000017500000006666113065111230012677 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cstable.h" #include "redfsm.h" #include "gendata.h" /* Determine if we should use indicies or not. */ void CSharpTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &CSharpTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &CSharpTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &CSharpTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &CSharpTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &CSharpTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpTabCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, true ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpTabCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpTabCodeGen::COND_OFFSETS() { out << "\t"; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the key offset ahead. */ curKeyOffset += st->stateCondList.length(); } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::KEY_OFFSETS() { out << "\t"; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the key offset ahead. */ curKeyOffset += st->outSingle.length() + st->outRange.length()*2; } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::INDEX_OFFSETS() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ curIndOffset += st->outSingle.length() + st->outRange.length(); if ( st->defTrans != 0 ) curIndOffset += 1; } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::COND_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->stateCondList.length(); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::SINGLE_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->outSingle.length(); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::RANGE_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit length of range index. */ out << st->outRange.length(); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::TO_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::FROM_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::EOF_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::EOF_TRANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpTabCodeGen::COND_KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Lower key. */ out << ALPHA_KEY( sc->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << ALPHA_KEY( sc->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ if ( keyOps->alphType->isChar ) out << "(char) " << 0 << "\n"; else out << 0 << "\n"; return out; } std::ostream &CSharpTabCodeGen::COND_SPACES() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Cond Space id. */ out << sc->condSpace->condSpaceId << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &CSharpTabCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << ALPHA_KEY( stel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ out << ALPHA_KEY( rtel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << ALPHA_KEY( rtel->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ if ( keyOps->alphType->isChar ) out << "(char) " << 0 << "\n"; else out << 0 << "\n"; return out; } std::ostream &CSharpTabCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << stel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { out << rtel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { out << st->defTrans->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &CSharpTabCodeGen::TRANS_TARGS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &CSharpTabCodeGen::TRANS_ACTIONS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &CSharpTabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } std::ostream &CSharpTabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } void CSharpTabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{" << vCS() << " = " << gotoDest << ";"; ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void CSharpTabCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{" << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void CSharpTabCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void CSharpTabCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void CSharpTabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void CSharpTabCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void CSharpTabCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << ";"; ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpTabCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << ");"; ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpTabCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{"; ret << vCS() << " = " << STACK() << "[--" << TOP() << "]; "; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "}"; } ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void CSharpTabCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }"; } void CSharpTabCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void CSharpTabCodeGen::LOCATE_TRANS() { out << " _keys = " << KO() + "[" + vCS() + "]" << ";\n" " _trans = " << CAST(transType) << IO() << "[" << vCS() << "];\n" "\n" " _klen = " << SL() << "[" << vCS() << "];\n" " if ( _klen > 0 ) {\n" " " << signedKeysType << " _lower = _keys;\n" " " << signedKeysType << " _mid;\n" " " << signedKeysType << " _upper = " << CAST(signedKeysType) << " (_keys + _klen - 1);\n" " while (true) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = " << CAST(signedKeysType) << " (_lower + ((_upper-_lower) >> 1));\n" " if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n" " _upper = " << CAST(signedKeysType) << " (_mid - 1);\n" " else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid] )\n" " _lower = " << CAST(signedKeysType) << " (_mid + 1);\n" " else {\n" " _trans += " << CAST(transType) << " (_mid - _keys);\n" " goto _match;\n" " }\n" " }\n" " _keys += " << CAST(keysType) << " _klen;\n" " _trans += " << CAST(transType) << " _klen;\n" " }\n" "\n" " _klen = " << RL() << "[" << vCS() << "];\n" " if ( _klen > 0 ) {\n" " " << signedKeysType << " _lower = _keys;\n" " " << signedKeysType << " _mid;\n" " " << signedKeysType << " _upper = " << CAST(signedKeysType) << " (_keys + (_klen<<1) - 2);\n" " while (true) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = " << CAST(signedKeysType) << " (_lower + (((_upper-_lower) >> 1) & ~1));\n" " if ( " << GET_WIDE_KEY() << " < " << K() << "[_mid] )\n" " _upper = " << CAST(signedKeysType) << " (_mid - 2);\n" " else if ( " << GET_WIDE_KEY() << " > " << K() << "[_mid+1] )\n" " _lower = " << CAST(signedKeysType) << " (_mid + 2);\n" " else {\n" " _trans += " << CAST(transType) << "((_mid - _keys)>>1);\n" " goto _match;\n" " }\n" " }\n" " _trans += " << CAST(transType) << " _klen;\n" " }\n" "\n"; } void CSharpTabCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << ";\n" " _klen = " << CL() << "[" << vCS() << "];\n" " _keys = " << CAST(keysType) << " ("<< CO() << "[" << vCS() << "]*2);\n" " if ( _klen > 0 ) {\n" " " << signedKeysType << " _lower = _keys;\n" " " << signedKeysType << " _mid;\n" " " << signedKeysType << " _upper = " << CAST(signedKeysType) << " (_keys + (_klen<<1) - 2);\n" " while (true) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = " << CAST(signedKeysType) << " (_lower + (((_upper-_lower) >> 1) & ~1));\n" " if ( " << GET_WIDE_KEY() << " < " << CK() << "[_mid] )\n" " _upper = " << CAST(signedKeysType) << " (_mid - 2);\n" " else if ( " << GET_WIDE_KEY() << " > " << CK() << "[_mid+1] )\n" " _lower = " << CAST(signedKeysType) << " (_mid + 2);\n" " else {\n" " switch ( " << C() << "[" << CO() << "[" << vCS() << "]" " + ((_mid - _keys)>>1)] ) {\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId << ": {\n"; out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } out << " break;\n" " }\n"; } SWITCH_DEFAULT(); out << " }\n" " break;\n" " }\n" " }\n" " }\n" "\n"; } void CSharpTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " {\n" " " << klenType << " _klen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n" " " << transType << " _trans;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " int _acts;\n" " int _nacts;\n"; } out << " " << keysType << " _keys;\n" "\n"; // " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n" if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << FSA() << "[" + vCS() + "]" << ";\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); out << "_match:\n"; if ( useIndicies ) out << " _trans = " << CAST(transType) << I() << "[_trans];\n"; if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " _acts = " << TA() << "[_trans]" << ";\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 )\n {\n" " switch ( " << A() << "[_acts++] )\n {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << TSA() << "[" << vCS() << "]" << ";\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << CAST(transType) << " (" << ET() << "[" << vCS() << "] - 1);\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " int __acts = " << EA() << "[" << vCS() << "]" << ";\n" " int __nacts = " << A() << "[__acts++];\n" " while ( __nacts-- > 0 ) {\n" " switch ( " << A() << "[__acts++] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } void CSharpTabCodeGen::initVarTypes() { int klenMax = MAX(MAX(redFsm->maxCondLen, redFsm->maxRangeLen), redFsm->maxSingleLen); int keysMax = MAX(MAX(redFsm->maxKeyOffset, klenMax), redFsm->maxCondOffset); int transMax = MAX(MAX(redFsm->maxIndex+1, redFsm->maxIndexOffset), keysMax); transMax = MAX(transMax, klenMax); transType = ARRAY_TYPE(transMax); klenType = ARRAY_TYPE(klenMax); keysType = ARRAY_TYPE(keysMax); signedKeysType = ARRAY_TYPE(keysMax, true); } ragel-6.10/ragel/mlflat.h0000664000175000017500000000551313065111230012173 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MLFLAT_H #define _MLFLAT_H #include #include "mlcodegen.h" /* Forwards. */ //struct CodeGenData; //struct NameInst; //struct RedTransAp; //struct RedStateAp; /* * OCamlFlatCodeGen */ class OCamlFlatCodeGen : public OCamlCodeGen { public: OCamlFlatCodeGen( ostream &out ) : OCamlCodeGen(out) {} virtual ~OCamlFlatCodeGen() { } protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &FLAT_INDEX_OFFSET(); std::ostream &KEY_SPANS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); void LOCATE_TRANS(); std::ostream &COND_INDEX_OFFSET(); void COND_TRANSLATE(); std::ostream &CONDS(); std::ostream &COND_KEYS(); std::ostream &COND_KEY_SPANS(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); void initVarTypes(); string slenType, transType, indsType, condsType; }; #endif ragel-6.10/ragel/rlparse.kl0000664000175000017500000012246113065111230012545 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rlparse.h" #include "ragel.h" #include #include #include using std::cout; using std::cerr; using std::endl; %%{ parser Parser; include "rlparse.kh"; start: section_list; section_list: section_list statement_list TK_EndSection; section_list: ; statement_list: statement_list statement; statement_list: ; statement: assignment commit; statement: instantiation commit; statement: action_spec commit; statement: alphtype_spec commit; statement: range_spec commit; statement: getkey_spec commit; statement: access_spec commit; statement: variable_spec commit; statement: export_block commit; statement: pre_push_spec commit; statement: post_pop_spec commit; statement: length_spec commit; length_spec: KW_Length TK_Word ';' final { LengthDef *lengthDef = new LengthDef( $2->data ); pd->lengthDefList.append( lengthDef ); /* Generic creation of machine for instantiation and assignment. */ MachineDef *machineDef = new MachineDef( lengthDef ); tryMachineDef( $2->loc, $2->data, machineDef, false ); }; pre_push_spec: KW_PrePush '{' inline_block '}' final { if ( pd->prePushExpr != 0 ) { /* Recover by just ignoring the duplicate. */ error($2->loc) << "pre_push code already defined" << endl; } pd->prePushExpr = $3->inlineList; }; post_pop_spec: KW_PostPop '{' inline_block '}' final { if ( pd->postPopExpr != 0 ) { /* Recover by just ignoring the duplicate. */ error($2->loc) << "post_pop code already defined" << endl; } pd->postPopExpr = $3->inlineList; }; export_open: KW_Export final { exportContext.append( true ); }; nonterm opt_export { bool isSet; }; opt_export: export_open final { $$->isSet = true; }; opt_export: final { $$->isSet = false; }; export_block: export_open '{' statement_list '}' final { exportContext.remove( exportContext.length()-1 ); }; assignment: opt_export machine_name '=' join ';' final { /* Main machine must be an instance. */ bool isInstance = false; if ( strcmp($2->token.data, mainMachine) == 0 ) { warning($2->token.loc) << "main machine will be implicitly instantiated" << endl; isInstance = true; } /* Generic creation of machine for instantiation and assignment. */ MachineDef *machineDef = new MachineDef( $4->join ); tryMachineDef( $2->token.loc, $2->token.data, machineDef, isInstance ); if ( $1->isSet ) exportContext.remove( exportContext.length()-1 ); $4->join->loc = $3->loc; }; instantiation: opt_export machine_name TK_ColonEquals join_or_lm ';' final { /* Generic creation of machine for instantiation and assignment. */ tryMachineDef( $2->token.loc, $2->token.data, $4->machineDef, true ); if ( $1->isSet ) exportContext.remove( exportContext.length()-1 ); /* Pass a location to join_or_lm */ if ( $4->machineDef->join != 0 ) $4->machineDef->join->loc = $3->loc; }; type token_type { Token token; }; nonterm machine_name uses token_type; machine_name: TK_Word final { /* Make/get the priority key. The name may have already been referenced * and therefore exist. */ PriorDictEl *priorDictEl; if ( pd->priorDict.insert( $1->data, pd->nextPriorKey, &priorDictEl ) ) pd->nextPriorKey += 1; pd->curDefPriorKey = priorDictEl->value; /* Make/get the local error key. */ LocalErrDictEl *localErrDictEl; if ( pd->localErrDict.insert( $1->data, pd->nextLocalErrKey, &localErrDictEl ) ) pd->nextLocalErrKey += 1; pd->curDefLocalErrKey = localErrDictEl->value; $$->token = *$1; }; action_spec: KW_Action TK_Word '{' inline_block '}' final { if ( pd->actionDict.find( $2->data ) ) { /* Recover by just ignoring the duplicate. */ error($2->loc) << "action \"" << $2->data << "\" already defined" << endl; } else { //cerr << "NEW ACTION " << $2->data << " " << $4->inlineList << endl; /* Add the action to the list of actions. */ Action *newAction = new Action( $3->loc, $2->data, $4->inlineList, pd->nextCondId++ ); /* Insert to list and dict. */ pd->actionList.append( newAction ); pd->actionDict.insert( newAction ); } }; # Specifies the data type of the input alphabet. One or two words followed by a # semi-colon. alphtype_spec: KW_AlphType TK_Word TK_Word ';' final { if ( ! pd->setAlphType( $1->loc, $2->data, $3->data ) ) { // Recover by ignoring the alphtype statement. error($2->loc) << "\"" << $2->data << " " << $3->data << "\" is not a valid alphabet type" << endl; } }; alphtype_spec: KW_AlphType TK_Word ';' final { if ( ! pd->setAlphType( $1->loc, $2->data ) ) { // Recover by ignoring the alphtype statement. error($2->loc) << "\"" << $2->data << "\" is not a valid alphabet type" << endl; } }; # Specifies a range to assume that the input characters will fall into. range_spec: KW_Range alphabet_num alphabet_num ';' final { // Save the upper and lower ends of the range and emit the line number. pd->lowerNum = $2->token.data; pd->upperNum = $3->token.data; pd->rangeLowLoc = $2->token.loc; pd->rangeHighLoc = $3->token.loc; }; getkey_spec: KW_GetKey inline_expr ';' final { pd->getKeyExpr = $2->inlineList; }; access_spec: KW_Access inline_expr ';' final { pd->accessExpr = $2->inlineList; }; variable_spec: KW_Variable opt_whitespace TK_Word inline_expr ';' final { /* FIXME: Need to implement the rest of this. */ bool wasSet = pd->setVariable( $3->data, $4->inlineList ); if ( !wasSet ) error($3->loc) << "bad variable name" << endl; }; opt_whitespace: opt_whitespace IL_WhiteSpace; opt_whitespace: ; # # Expressions # nonterm join_or_lm { MachineDef *machineDef; }; join_or_lm: join final { $$->machineDef = new MachineDef( $1->join ); }; join_or_lm: TK_BarStar lm_part_list '*' '|' final { /* Create a new factor going to a longest match structure. Record * in the parse data that we have a longest match. */ LongestMatch *lm = new LongestMatch( $1->loc, $2->lmPartList ); pd->lmList.append( lm ); for ( LmPartList::Iter lmp = *($2->lmPartList); lmp.lte(); lmp++ ) lmp->longestMatch = lm; $$->machineDef = new MachineDef( lm ); }; nonterm lm_part_list { LmPartList *lmPartList; }; lm_part_list: lm_part_list longest_match_part final { if ( $2->lmPart != 0 ) $1->lmPartList->append( $2->lmPart ); $$->lmPartList = $1->lmPartList; }; lm_part_list: longest_match_part final { /* Create a new list with the part. */ $$->lmPartList = new LmPartList; if ( $1->lmPart != 0 ) $$->lmPartList->append( $1->lmPart ); }; nonterm longest_match_part { LongestMatchPart *lmPart; }; longest_match_part: action_spec final { $$->lmPart = 0; }; longest_match_part: assignment final { $$->lmPart = 0; }; longest_match_part: join opt_lm_part_action ';' final { $$->lmPart = 0; Action *action = $2->action; if ( action != 0 ) action->isLmAction = true; $$->lmPart = new LongestMatchPart( $1->join, action, $3->loc, pd->nextLongestMatchId++ ); /* Provide a location to join. Unfortunately We don't * have the start of the join as in other occurances. Use the end. */ $1->join->loc = $3->loc; }; nonterm opt_lm_part_action { Action *action; }; opt_lm_part_action: TK_DoubleArrow action_embed final { $$->action = $2->action; }; opt_lm_part_action: action_embed_block final { $$->action = $1->action; }; opt_lm_part_action: final { $$->action = 0; }; nonterm join { Join *join; }; join: join ',' expression final { /* Append the expression to the list and return it. */ $1->join->exprList.append( $3->expression ); $$->join = $1->join; }; join: expression final { $$->join = new Join( $1->expression ); }; nonterm expression { Expression *expression; }; expression: expression '|' term_short final { $$->expression = new Expression( $1->expression, $3->term, Expression::OrType ); }; expression: expression '&' term_short final { $$->expression = new Expression( $1->expression, $3->term, Expression::IntersectType ); }; expression: expression '-' term_short final { $$->expression = new Expression( $1->expression, $3->term, Expression::SubtractType ); }; expression: expression TK_DashDash term_short final { $$->expression = new Expression( $1->expression, $3->term, Expression::StrongSubtractType ); }; expression: term_short final { $$->expression = new Expression( $1->term ); }; # This is where we resolve the ambiguity involving -. By default ragel tries to # do a longest match, which gives precedence to a concatenation because it is # innermost. What we need is to force term into a shortest match so that when - # is seen it doesn't try to extend term with a concatenation, but ends term and # goes for a subtraction. # # The shortest tag overrides the default longest match action ordering strategy # and instead forces a shortest match stragegy. The wrap the term production in # a new nonterminal 'term_short' to guarantee the shortest match behaviour. shortest term_short; nonterm term_short { Term *term; }; term_short: term final { $$->term = $1->term; }; nonterm term { Term *term; }; term: term factor_with_label final { $$->term = new Term( $1->term, $2->factorWithAug ); }; term: term '.' factor_with_label final { $$->term = new Term( $1->term, $3->factorWithAug ); }; term: term TK_ColonGt factor_with_label final { $$->term = new Term( $1->term, $3->factorWithAug, Term::RightStartType ); }; term: term TK_ColonGtGt factor_with_label final { $$->term = new Term( $1->term, $3->factorWithAug, Term::RightFinishType ); }; term: term TK_LtColon factor_with_label final { $$->term = new Term( $1->term, $3->factorWithAug, Term::LeftType ); }; term: factor_with_label final { $$->term = new Term( $1->factorWithAug ); }; nonterm factor_with_label { FactorWithAug *factorWithAug; }; factor_with_label: TK_Word ':' factor_with_label final { /* Add the label to the list and pass the factor up. */ $3->factorWithAug->labels.prepend( Label($1->loc, $1->data) ); $$->factorWithAug = $3->factorWithAug; }; factor_with_label: factor_with_ep final { $$->factorWithAug = $1->factorWithAug; }; nonterm factor_with_ep { FactorWithAug *factorWithAug; }; factor_with_ep: factor_with_ep TK_Arrow local_state_ref final { /* Add the target to the list and return the factor object. */ $1->factorWithAug->epsilonLinks.append( EpsilonLink( $2->loc, nameRef ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_ep: factor_with_aug final { $$->factorWithAug = $1->factorWithAug; }; nonterm factor_with_aug { FactorWithAug *factorWithAug; }; factor_with_aug: factor_with_aug aug_type_base action_embed final { /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, 0, $3->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_base priority_aug final { /* Append the named priority to the factorWithAug and pass it up. */ $1->factorWithAug->priorityAugs.append( PriorityAug( $2->augType, pd->curDefPriorKey, $3->priorityNum ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_base '(' priority_name ',' priority_aug ')' final { /* Append the priority using a default name. */ $1->factorWithAug->priorityAugs.append( PriorityAug( $2->augType, $4->priorityName, $6->priorityNum ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_cond action_embed final { $1->factorWithAug->conditions.append( ConditionTest( $2->loc, $2->augType, $3->action, true ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_cond '!' action_embed final { $1->factorWithAug->conditions.append( ConditionTest( $2->loc, $2->augType, $4->action, false ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_to_state action_embed final { /* Append the action, pass it up. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, 0, $3->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_from_state action_embed final { /* Append the action, pass it up. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, 0, $3->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_eof action_embed final { /* Append the action, pass it up. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, 0, $3->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_gbl_error action_embed final { /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, pd->curDefLocalErrKey, $3->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_local_error action_embed final { /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, pd->curDefLocalErrKey, $3->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_aug aug_type_local_error '(' local_err_name ',' action_embed ')' final { /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ $1->factorWithAug->actions.append( ParserAction( $2->loc, $2->augType, $4->error_name, $6->action ) ); $$->factorWithAug = $1->factorWithAug; }; factor_with_aug: factor_with_rep final { $$->factorWithAug = new FactorWithAug( $1->factorWithRep ); }; type aug_type { InputLoc loc; AugType augType; }; # Classes of transtions on which to embed actions or change priorities. nonterm aug_type_base uses aug_type; aug_type_base: '@' final { $$->loc = $1->loc; $$->augType = at_finish; }; aug_type_base: '%' final { $$->loc = $1->loc; $$->augType = at_leave; }; aug_type_base: '$' final { $$->loc = $1->loc; $$->augType = at_all; }; aug_type_base: '>' final { $$->loc = $1->loc; $$->augType = at_start; }; # Embedding conditions. nonterm aug_type_cond uses aug_type; aug_type_cond: TK_StartCond final { $$->loc = $1->loc; $$->augType = at_start; }; aug_type_cond: '>' KW_When final { $$->loc = $1->loc; $$->augType = at_start; }; aug_type_cond: TK_AllCond final { $$->loc = $1->loc; $$->augType = at_all; }; aug_type_cond: '$' KW_When final { $$->loc = $1->loc; $$->augType = at_all; }; aug_type_cond: TK_LeavingCond final { $$->loc = $1->loc; $$->augType = at_leave; }; aug_type_cond: '%' KW_When final { $$->loc = $1->loc; $$->augType = at_leave; }; aug_type_cond: KW_When final { $$->loc = $1->loc; $$->augType = at_all; }; aug_type_cond: KW_InWhen final { $$->loc = $1->loc; $$->augType = at_start; }; aug_type_cond: KW_OutWhen final { $$->loc = $1->loc; $$->augType = at_leave; }; # # To state actions. # nonterm aug_type_to_state uses aug_type; aug_type_to_state: TK_StartToState final { $$->loc = $1->loc; $$->augType = at_start_to_state; }; aug_type_to_state: '>' KW_To final { $$->loc = $1->loc; $$->augType = at_start_to_state; }; aug_type_to_state: TK_NotStartToState final { $$->loc = $1->loc; $$->augType = at_not_start_to_state; }; aug_type_to_state: '<' KW_To final { $$->loc = $1->loc; $$->augType = at_not_start_to_state; }; aug_type_to_state: TK_AllToState final { $$->loc = $1->loc; $$->augType = at_all_to_state; }; aug_type_to_state: '$' KW_To final { $$->loc = $1->loc; $$->augType = at_all_to_state; }; aug_type_to_state: TK_FinalToState final { $$->loc = $1->loc; $$->augType = at_final_to_state; }; aug_type_to_state: '%' KW_To final { $$->loc = $1->loc; $$->augType = at_final_to_state; }; aug_type_to_state: TK_NotFinalToState final { $$->loc = $1->loc; $$->augType = at_not_final_to_state; }; aug_type_to_state: '@' KW_To final { $$->loc = $1->loc; $$->augType = at_not_final_to_state; }; aug_type_to_state: TK_MiddleToState final { $$->loc = $1->loc; $$->augType = at_middle_to_state; }; aug_type_to_state: TK_Middle KW_To final { $$->loc = $1->loc; $$->augType = at_middle_to_state; }; # # From state actions. # nonterm aug_type_from_state uses aug_type; aug_type_from_state: TK_StartFromState final { $$->loc = $1->loc; $$->augType = at_start_from_state; }; aug_type_from_state: '>' KW_From final { $$->loc = $1->loc; $$->augType = at_start_from_state; }; aug_type_from_state: TK_NotStartFromState final { $$->loc = $1->loc; $$->augType = at_not_start_from_state; }; aug_type_from_state: '<' KW_From final { $$->loc = $1->loc; $$->augType = at_not_start_from_state; }; aug_type_from_state: TK_AllFromState final { $$->loc = $1->loc; $$->augType = at_all_from_state; }; aug_type_from_state: '$' KW_From final { $$->loc = $1->loc; $$->augType = at_all_from_state; }; aug_type_from_state: TK_FinalFromState final { $$->loc = $1->loc; $$->augType = at_final_from_state; }; aug_type_from_state: '%' KW_From final { $$->loc = $1->loc; $$->augType = at_final_from_state; }; aug_type_from_state: TK_NotFinalFromState final { $$->loc = $1->loc; $$->augType = at_not_final_from_state; }; aug_type_from_state: '@' KW_From final { $$->loc = $1->loc; $$->augType = at_not_final_from_state; }; aug_type_from_state: TK_MiddleFromState final { $$->loc = $1->loc; $$->augType = at_middle_from_state; }; aug_type_from_state: TK_Middle KW_From final { $$->loc = $1->loc; $$->augType = at_middle_from_state; }; # # Eof state actions. # nonterm aug_type_eof uses aug_type; aug_type_eof: TK_StartEOF final { $$->loc = $1->loc; $$->augType = at_start_eof; }; aug_type_eof: '>' KW_Eof final { $$->loc = $1->loc; $$->augType = at_start_eof; }; aug_type_eof: TK_NotStartEOF final { $$->loc = $1->loc; $$->augType = at_not_start_eof; }; aug_type_eof: '<' KW_Eof final { $$->loc = $1->loc; $$->augType = at_not_start_eof; }; aug_type_eof: TK_AllEOF final { $$->loc = $1->loc; $$->augType = at_all_eof; }; aug_type_eof: '$' KW_Eof final { $$->loc = $1->loc; $$->augType = at_all_eof; }; aug_type_eof: TK_FinalEOF final { $$->loc = $1->loc; $$->augType = at_final_eof; }; aug_type_eof: '%' KW_Eof final { $$->loc = $1->loc; $$->augType = at_final_eof; }; aug_type_eof: TK_NotFinalEOF final { $$->loc = $1->loc; $$->augType = at_not_final_eof; }; aug_type_eof: '@' KW_Eof final { $$->loc = $1->loc; $$->augType = at_not_final_eof; }; aug_type_eof: TK_MiddleEOF final { $$->loc = $1->loc; $$->augType = at_middle_eof; }; aug_type_eof: TK_Middle KW_Eof final { $$->loc = $1->loc; $$->augType = at_middle_eof; }; # # Global error actions. # nonterm aug_type_gbl_error uses aug_type; aug_type_gbl_error: TK_StartGblError final { $$->loc = $1->loc; $$->augType = at_start_gbl_error; }; aug_type_gbl_error: '>' KW_Err final { $$->loc = $1->loc; $$->augType = at_start_gbl_error; }; aug_type_gbl_error: TK_NotStartGblError final { $$->loc = $1->loc; $$->augType = at_not_start_gbl_error; }; aug_type_gbl_error: '<' KW_Err final { $$->loc = $1->loc; $$->augType = at_not_start_gbl_error; }; aug_type_gbl_error: TK_AllGblError final { $$->loc = $1->loc; $$->augType = at_all_gbl_error; }; aug_type_gbl_error: '$' KW_Err final { $$->loc = $1->loc; $$->augType = at_all_gbl_error; }; aug_type_gbl_error: TK_FinalGblError final { $$->loc = $1->loc; $$->augType = at_final_gbl_error; }; aug_type_gbl_error: '%' KW_Err final { $$->loc = $1->loc; $$->augType = at_final_gbl_error; }; aug_type_gbl_error: TK_NotFinalGblError final { $$->loc = $1->loc; $$->augType = at_not_final_gbl_error; }; aug_type_gbl_error: '@' KW_Err final { $$->loc = $1->loc; $$->augType = at_not_final_gbl_error; }; aug_type_gbl_error: TK_MiddleGblError final { $$->loc = $1->loc; $$->augType = at_middle_gbl_error; }; aug_type_gbl_error: TK_Middle KW_Err final { $$->loc = $1->loc; $$->augType = at_middle_gbl_error; }; # # Local error actions. # nonterm aug_type_local_error uses aug_type; aug_type_local_error: TK_StartLocalError final { $$->loc = $1->loc; $$->augType = at_start_local_error; }; aug_type_local_error: '>' KW_Lerr final { $$->loc = $1->loc; $$->augType = at_start_local_error; }; aug_type_local_error: TK_NotStartLocalError final { $$->loc = $1->loc; $$->augType = at_not_start_local_error; }; aug_type_local_error: '<' KW_Lerr final { $$->loc = $1->loc; $$->augType = at_not_start_local_error; }; aug_type_local_error: TK_AllLocalError final { $$->loc = $1->loc; $$->augType = at_all_local_error; }; aug_type_local_error: '$' KW_Lerr final { $$->loc = $1->loc; $$->augType = at_all_local_error; }; aug_type_local_error: TK_FinalLocalError final { $$->loc = $1->loc; $$->augType = at_final_local_error; }; aug_type_local_error: '%' KW_Lerr final { $$->loc = $1->loc; $$->augType = at_final_local_error; }; aug_type_local_error: TK_NotFinalLocalError final { $$->loc = $1->loc; $$->augType = at_not_final_local_error; }; aug_type_local_error: '@' KW_Lerr final { $$->loc = $1->loc; $$->augType = at_not_final_local_error; }; aug_type_local_error: TK_MiddleLocalError final { $$->loc = $1->loc; $$->augType = at_middle_local_error; }; aug_type_local_error: TK_Middle KW_Lerr final { $$->loc = $1->loc; $$->augType = at_middle_local_error; }; type action_ref { Action *action; }; # Different ways to embed actions. A TK_Word is reference to an action given by # the user as a statement in the fsm specification. An action can also be # specified immediately. nonterm action_embed uses action_ref; action_embed: action_embed_word final { $$->action = $1->action; }; action_embed: '(' action_embed_word ')' final { $$->action = $2->action; }; action_embed: action_embed_block final { $$->action = $1->action; }; nonterm action_embed_word uses action_ref; action_embed_word: TK_Word final { /* Set the name in the actionDict. */ Action *action = pd->actionDict.find( $1->data ); if ( action != 0 ) { /* Pass up the action element */ $$->action = action; } else { /* Will recover by returning null as the action. */ error($1->loc) << "action lookup of \"" << $1->data << "\" failed" << endl; $$->action = 0; } }; nonterm action_embed_block uses action_ref; action_embed_block: '{' inline_block '}' final { /* Create the action, add it to the list and pass up. */ Action *newAction = new Action( $1->loc, 0, $2->inlineList, pd->nextCondId++ ); pd->actionList.append( newAction ); $$->action = newAction; }; nonterm priority_name { int priorityName; }; # A specified priority name. Looks up the name in the current priority # dictionary. priority_name: TK_Word final { // Lookup/create the priority key. PriorDictEl *priorDictEl; if ( pd->priorDict.insert( $1->data, pd->nextPriorKey, &priorDictEl ) ) pd->nextPriorKey += 1; // Use the inserted/found priority key. $$->priorityName = priorDictEl->value; }; nonterm priority_aug { int priorityNum; }; # Priority change specs. priority_aug: priority_aug_num final { // Convert the priority number to a long. Check for overflow. errno = 0; //cerr << "PRIOR AUG: " << $1->token.data << endl; long aug = strtol( $1->token.data, 0, 10 ); if ( errno == ERANGE && aug == LONG_MAX ) { /* Priority number too large. Recover by setting the priority to 0. */ error($1->token.loc) << "priority number " << $1->token.data << " overflows" << endl; $$->priorityNum = 0; } else if ( errno == ERANGE && aug == LONG_MIN ) { /* Priority number too large in the neg. Recover by using 0. */ error($1->token.loc) << "priority number " << $1->token.data << " underflows" << endl; $$->priorityNum = 0; } else { /* No overflow or underflow. */ $$->priorityNum = aug; } }; nonterm priority_aug_num uses token_type; priority_aug_num: TK_UInt final { $$->token = *$1; }; priority_aug_num: '+' TK_UInt final { $$->token.set( "+", 1 ); $$->token.loc = $1->loc; $$->token.append( *$2 ); }; priority_aug_num: '-' TK_UInt final { $$->token.set( "-", 1 ); $$->token.loc = $1->loc; $$->token.append( *$2 ); }; nonterm local_err_name { int error_name; }; local_err_name: TK_Word final { /* Lookup/create the priority key. */ LocalErrDictEl *localErrDictEl; if ( pd->localErrDict.insert( $1->data, pd->nextLocalErrKey, &localErrDictEl ) ) pd->nextLocalErrKey += 1; /* Use the inserted/found priority key. */ $$->error_name = localErrDictEl->value; }; # The fourth level of precedence. These are the trailing unary operators that # allow for repetition. nonterm factor_with_rep { FactorWithRep *factorWithRep; }; factor_with_rep: factor_with_rep '*' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, 0, 0, FactorWithRep::StarType ); }; factor_with_rep: factor_with_rep TK_StarStar final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, 0, 0, FactorWithRep::StarStarType ); }; factor_with_rep: factor_with_rep '?' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, 0, 0, FactorWithRep::OptionalType ); }; factor_with_rep: factor_with_rep '+' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, 0, 0, FactorWithRep::PlusType ); }; factor_with_rep: factor_with_rep '{' factor_rep_num '}' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, $3->rep, 0, FactorWithRep::ExactType ); }; factor_with_rep: factor_with_rep '{' ',' factor_rep_num '}' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, 0, $4->rep, FactorWithRep::MaxType ); }; factor_with_rep: factor_with_rep '{' factor_rep_num ',' '}' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, $3->rep, 0, FactorWithRep::MinType ); }; factor_with_rep: factor_with_rep '{' factor_rep_num ',' factor_rep_num '}' final { $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep, $3->rep, $5->rep, FactorWithRep::RangeType ); }; factor_with_rep: factor_with_neg final { $$->factorWithRep = new FactorWithRep( $1->factorWithNeg ); }; nonterm factor_rep_num { int rep; }; factor_rep_num: TK_UInt final { // Convert the priority number to a long. Check for overflow. errno = 0; long rep = strtol( $1->data, 0, 10 ); if ( errno == ERANGE && rep == LONG_MAX ) { // Repetition too large. Recover by returing repetition 1. */ error($1->loc) << "repetition number " << $1->data << " overflows" << endl; $$->rep = 1; } else { // Cannot be negative, so no overflow. $$->rep = rep; } }; # # The fifth level up in precedence. Negation. # nonterm factor_with_neg { FactorWithNeg *factorWithNeg; }; factor_with_neg: '!' factor_with_neg final { $$->factorWithNeg = new FactorWithNeg( $1->loc, $2->factorWithNeg, FactorWithNeg::NegateType ); }; factor_with_neg: '^' factor_with_neg final { $$->factorWithNeg = new FactorWithNeg( $1->loc, $2->factorWithNeg, FactorWithNeg::CharNegateType ); }; factor_with_neg: factor final { $$->factorWithNeg = new FactorWithNeg( $1->factor ); }; nonterm factor { Factor *factor; }; factor: TK_Literal final { /* Create a new factor node going to a concat literal. */ $$->factor = new Factor( new Literal( *$1, Literal::LitString ) ); }; factor: alphabet_num final { /* Create a new factor node going to a literal number. */ $$->factor = new Factor( new Literal( $1->token, Literal::Number ) ); }; factor: TK_Word final { /* Find the named graph. */ GraphDictEl *gdNode = pd->graphDict.find( $1->data ); if ( gdNode == 0 ) { /* Recover by returning null as the factor node. */ error($1->loc) << "graph lookup of \"" << $1->data << "\" failed" << endl; $$->factor = 0; } else if ( gdNode->isInstance ) { /* Recover by retuning null as the factor node. */ error($1->loc) << "references to graph instantiations not allowed " "in expressions" << endl; $$->factor = 0; } else { /* Create a factor node that is a lookup of an expression. */ $$->factor = new Factor( $1->loc, gdNode->value ); } }; factor: RE_SqOpen regular_expr_or_data RE_SqClose final { /* Create a new factor node going to an OR expression. */ $$->factor = new Factor( new ReItem( $1->loc, $2->reOrBlock, ReItem::OrBlock ) ); }; factor: RE_SqOpenNeg regular_expr_or_data RE_SqClose final { /* Create a new factor node going to a negated OR expression. */ $$->factor = new Factor( new ReItem( $1->loc, $2->reOrBlock, ReItem::NegOrBlock ) ); }; factor: RE_Slash regular_expr RE_Slash final { if ( $3->length > 1 ) { for ( char *p = $3->data; *p != 0; p++ ) { if ( *p == 'i' ) $2->regExpr->caseInsensitive = true; } } /* Create a new factor node going to a regular exp. */ $$->factor = new Factor( $2->regExpr ); }; factor: range_lit TK_DotDot range_lit final { /* Create a new factor node going to a range. */ $$->factor = new Factor( new Range( $1->literal, $3->literal ) ); }; factor: '(' join ')' final { /* Create a new factor going to a parenthesized join. */ $$->factor = new Factor( $2->join ); $2->join->loc = $1->loc; }; nonterm range_lit { Literal *literal; }; # Literals which can be the end points of ranges. range_lit: TK_Literal final { /* Range literas must have only one char. We restrict this in the parse tree. */ $$->literal = new Literal( *$1, Literal::LitString ); }; range_lit: alphabet_num final { /* Create a new literal number. */ $$->literal = new Literal( $1->token, Literal::Number ); }; nonterm alphabet_num uses token_type; # Any form of a number that can be used as a basic machine. */ alphabet_num: TK_UInt final { $$->token = *$1; }; alphabet_num: '-' TK_UInt final { $$->token.set( "-", 1 ); $$->token.loc = $1->loc; $$->token.append( *$2 ); }; alphabet_num: TK_Hex final { $$->token = *$1; }; # # Regular Expressions. # nonterm regular_expr { RegExpr *regExpr; }; # Parser for regular expression fsms. Any number of expression items which # generally gives a machine one character long or one character long stared. regular_expr: regular_expr regular_expr_item final { /* An optimization to lessen the tree size. If a non-starred char is * directly under the left side on the right and the right side is * another non-starred char then paste them together and return the * left side. Otherwise just put the two under a new reg exp node. */ if ( $2->reItem->type == ReItem::Data && !$2->reItem->star && $1->regExpr->type == RegExpr::RecurseItem && $1->regExpr->item->type == ReItem::Data && !$1->regExpr->item->star ) { /* Append the right side to the right side of the left and toss the * right side. */ $1->regExpr->item->token.append( $2->reItem->token ); delete $2->reItem; $$->regExpr = $1->regExpr; } else { $$->regExpr = new RegExpr( $1->regExpr, $2->reItem ); } }; regular_expr: final { /* Can't optimize the tree. */ $$->regExpr = new RegExpr(); }; nonterm regular_expr_item { ReItem *reItem; }; # RegularExprItems can be a character spec with an optional staring of the char. regular_expr_item: regular_expr_char RE_Star final { $1->reItem->star = true; $$->reItem = $1->reItem; }; regular_expr_item: regular_expr_char final { $$->reItem = $1->reItem; }; nonterm regular_expr_char { ReItem *reItem; }; # A character spec can be a set of characters inside of square parenthesis, a # dot specifying any character or some explicitly stated character. regular_expr_char: RE_SqOpen regular_expr_or_data RE_SqClose final { $$->reItem = new ReItem( $1->loc, $2->reOrBlock, ReItem::OrBlock ); }; regular_expr_char: RE_SqOpenNeg regular_expr_or_data RE_SqClose final { $$->reItem = new ReItem( $1->loc, $2->reOrBlock, ReItem::NegOrBlock ); }; regular_expr_char: RE_Dot final { $$->reItem = new ReItem( $1->loc, ReItem::Dot ); }; regular_expr_char: RE_Char final { $$->reItem = new ReItem( $1->loc, *$1 ); }; # The data inside of a [] expression in a regular expression. Accepts any # number of characters or ranges. */ nonterm regular_expr_or_data { ReOrBlock *reOrBlock; }; regular_expr_or_data: regular_expr_or_data regular_expr_or_char final { /* An optimization to lessen the tree size. If an or char is directly * under the left side on the right and the right side is another or * char then paste them together and return the left side. Otherwise * just put the two under a new or data node. */ if ( $2->reOrItem->type == ReOrItem::Data && $1->reOrBlock->type == ReOrBlock::RecurseItem && $1->reOrBlock->item->type == ReOrItem::Data ) { /* Append the right side to right side of the left and toss the * right side. */ $1->reOrBlock->item->token.append( $2->reOrItem->token ); delete $2->reOrItem; $$->reOrBlock = $1->reOrBlock; } else { /* Can't optimize, put the left and right under a new node. */ $$->reOrBlock = new ReOrBlock( $1->reOrBlock, $2->reOrItem ); } }; regular_expr_or_data: final { $$->reOrBlock = new ReOrBlock(); }; # A single character inside of an or expression. Can either be a character or a # set of characters. nonterm regular_expr_or_char { ReOrItem *reOrItem; }; regular_expr_or_char: RE_Char final { $$->reOrItem = new ReOrItem( $1->loc, *$1 ); }; regular_expr_or_char: RE_Char RE_Dash RE_Char final { $$->reOrItem = new ReOrItem( $2->loc, $1->data[0], $3->data[0] ); }; # # Inline Lists for inline host code. # type inline_list { InlineList *inlineList; }; nonterm inline_block uses inline_list; inline_block: inline_block inline_block_item final { /* Append the item to the list, return the list. */ $$->inlineList = $1->inlineList; $$->inlineList->append( $2->inlineItem ); }; inline_block: final { /* Start with empty list. */ $$->inlineList = new InlineList; }; type inline_item { InlineItem *inlineItem; }; nonterm inline_block_item uses inline_item; nonterm inline_block_interpret uses inline_item; inline_block_item: inline_expr_any final { $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text ); }; inline_block_item: inline_block_symbol final { $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text ); }; inline_block_item: inline_block_interpret final { /* Pass the inline item up. */ $$->inlineItem = $1->inlineItem; }; nonterm inline_block_symbol uses token_type; inline_block_symbol: ',' final { $$->token = *$1; }; inline_block_symbol: ';' final { $$->token = *$1; }; inline_block_symbol: '(' final { $$->token = *$1; }; inline_block_symbol: ')' final { $$->token = *$1; }; inline_block_symbol: '*' final { $$->token = *$1; }; inline_block_symbol: TK_NameSep final { $$->token = *$1; }; # Interpreted statements in a struct block. */ inline_block_interpret: inline_expr_interpret final { /* Pass up interpreted items of inline expressions. */ $$->inlineItem = $1->inlineItem; }; inline_block_interpret: KW_Hold ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Hold ); }; inline_block_interpret: KW_Exec inline_expr ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Exec ); $$->inlineItem->children = $2->inlineList; }; inline_block_interpret: KW_Goto state_ref ';' final { $$->inlineItem = new InlineItem( $1->loc, new NameRef(nameRef), InlineItem::Goto ); }; inline_block_interpret: KW_Goto '*' inline_expr ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::GotoExpr ); $$->inlineItem->children = $3->inlineList; }; inline_block_interpret: KW_Next state_ref ';' final { $$->inlineItem = new InlineItem( $1->loc, new NameRef(nameRef), InlineItem::Next ); }; inline_block_interpret: KW_Next '*' inline_expr ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::NextExpr ); $$->inlineItem->children = $3->inlineList; }; inline_block_interpret: KW_Call state_ref ';' final { $$->inlineItem = new InlineItem( $1->loc, new NameRef(nameRef), InlineItem::Call ); }; inline_block_interpret: KW_Call '*' inline_expr ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::CallExpr ); $$->inlineItem->children = $3->inlineList; }; inline_block_interpret: KW_Ret ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Ret ); }; inline_block_interpret: KW_Break ';' final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Break ); }; nonterm inline_expr uses inline_list; inline_expr: inline_expr inline_expr_item final { $$->inlineList = $1->inlineList; $$->inlineList->append( $2->inlineItem ); }; inline_expr: final { /* Init the list used for this expr. */ $$->inlineList = new InlineList; }; nonterm inline_expr_item uses inline_item; inline_expr_item: inline_expr_any final { /* Return a text segment. */ $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text ); }; inline_expr_item: inline_expr_symbol final { /* Return a text segment, must heap alloc the text. */ $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text ); }; inline_expr_item: inline_expr_interpret final{ /* Pass the inline item up. */ $$->inlineItem = $1->inlineItem; }; nonterm inline_expr_any uses token_type; inline_expr_any: IL_WhiteSpace try { $$->token = *$1; }; inline_expr_any: IL_Comment try { $$->token = *$1; }; inline_expr_any: IL_Literal try { $$->token = *$1; }; inline_expr_any: IL_Symbol try { $$->token = *$1; }; inline_expr_any: TK_UInt try { $$->token = *$1; }; inline_expr_any: TK_Hex try { $$->token = *$1; }; inline_expr_any: TK_Word try { $$->token = *$1; }; # Anything in a ExecValExpr that is not dynamically allocated. This includes # all special symbols caught in inline code except the semi. nonterm inline_expr_symbol uses token_type; inline_expr_symbol: ',' try { $$->token = *$1; }; inline_expr_symbol: '(' try { $$->token = *$1; }; inline_expr_symbol: ')' try { $$->token = *$1; }; inline_expr_symbol: '*' try { $$->token = *$1; }; inline_expr_symbol: TK_NameSep try { $$->token = *$1; }; nonterm inline_expr_interpret uses inline_item; inline_expr_interpret: KW_PChar final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::PChar ); }; inline_expr_interpret: KW_Char final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Char ); }; inline_expr_interpret: KW_CurState final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Curs ); }; inline_expr_interpret: KW_TargState final { $$->inlineItem = new InlineItem( $1->loc, InlineItem::Targs ); }; inline_expr_interpret: KW_Entry '(' state_ref ')' final { $$->inlineItem = new InlineItem( $1->loc, new NameRef(nameRef), InlineItem::Entry ); }; # A local state reference. Cannot have :: prefix. local_state_ref: no_name_sep state_ref_names; # Clear the name ref structure. no_name_sep: final { nameRef.empty(); }; # A qualified state reference. state_ref: opt_name_sep state_ref_names; # Optional leading name separator. opt_name_sep: TK_NameSep final { /* Insert an initial null pointer val to indicate the existence of the * initial name seperator. */ nameRef.setAs( 0 ); }; opt_name_sep: final { nameRef.empty(); }; # List of names separated by :: state_ref_names: state_ref_names TK_NameSep TK_Word final { nameRef.append( $3->data ); }; state_ref_names: TK_Word final { nameRef.append( $1->data ); }; }%% %%{ write types; write data; }%% void Parser::init() { %% write init; } int Parser::parseLangEl( int type, const Token *token ) { %% write exec; return errCount == 0 ? 0 : -1; } void Parser::tryMachineDef( InputLoc &loc, char *name, MachineDef *machineDef, bool isInstance ) { GraphDictEl *newEl = pd->graphDict.insert( name ); if ( newEl != 0 ) { /* New element in the dict, all good. */ newEl->value = new VarDef( name, machineDef ); newEl->isInstance = isInstance; newEl->loc = loc; newEl->value->isExport = exportContext[exportContext.length()-1]; /* It it is an instance, put on the instance list. */ if ( isInstance ) pd->instanceList.append( newEl ); } else { // Recover by ignoring the duplicate. error(loc) << "fsm \"" << name << "\" previously defined" << endl; } } ostream &Parser::parse_error( int tokId, Token &token ) { /* Maintain the error count. */ gblErrorCount += 1; cerr << token.loc << ": "; cerr << "at token "; if ( tokId < 128 ) cerr << "\"" << Parser_lelNames[tokId] << "\""; else cerr << Parser_lelNames[tokId]; if ( token.data != 0 ) cerr << " with data \"" << token.data << "\""; cerr << ": "; return cerr; } int Parser::token( InputLoc &loc, int tokId, char *tokstart, int toklen ) { Token token; token.data = tokstart; token.length = toklen; token.loc = loc; int res = parseLangEl( tokId, &token ); if ( res < 0 ) { parse_error(tokId, token) << "parse error" << endl; exit(1); } return res; } ragel-6.10/ragel/mlgoto.h0000664000175000017500000000573313065111230012221 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MLGOTO_H #define _MLGOTO_H #include #include "mlcodegen.h" /* Forwards. */ //struct CodeGenData; //struct NameInst; //struct RedTransAp; //struct RedStateAp; //struct GenStateCond; /* * OCamlGotoCodeGen */ class OCamlGotoCodeGen : virtual public OCamlCodeGen { public: OCamlGotoCodeGen( ostream &out ) : OCamlCodeGen(out) {} std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &STATE_GOTOS(); std::ostream &TRANSITIONS(); std::ostream &EXEC_FUNCS(); std::ostream &FINISH_CASES(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState ); virtual unsigned int TO_STATE_ACTION( RedStateAp *state ); virtual unsigned int FROM_STATE_ACTION( RedStateAp *state ); virtual unsigned int EOF_ACTION( RedStateAp *state ); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); void COND_TRANSLATE( GenStateCond *stateCond, int level ); void emitCondBSearch( RedStateAp *state, int level, int low, int high ); void STATE_CONDS( RedStateAp *state, bool genDefault ); virtual std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); void emitSingleSwitch( RedStateAp *state ); void emitRangeBSearch( RedStateAp *state, int level, int low, int high, RedTransAp* def ); /* Called from STATE_GOTOS just before writing the gotos */ virtual void GOTO_HEADER( RedStateAp *state ); virtual void STATE_GOTO_ERROR(); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/csfflat.h0000664000175000017500000000322013065111230012327 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CSFFLAT_H #define _CSFFLAT_H #include #include "csflat.h" /* Forwards. */ struct CodeGenData; /* * CSharpFFlatCodeGen */ class CSharpFFlatCodeGen : public CSharpFlatCodeGen { public: CSharpFFlatCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpFlatCodeGen(out) {} private: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/csfflat.cpp0000664000175000017500000002123713065111230012672 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "csfflat.h" #include "redfsm.h" #include "gendata.h" std::ostream &CSharpFFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &CSharpFFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &CSharpFFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &CSharpFFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &CSharpFFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &CSharpFFlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpFFlatCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &CSharpFFlatCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } void CSharpFFlatCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void CSharpFFlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " {\n" " " << slenType << " _slen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n"; out << " " << transType << " _trans"; if ( redFsm->anyConditions() ) out << ", _cond"; out << ";\n"; out << " " << "int _keys;\n" " " << indsType << " _inds;\n"; /* " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n" " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/ if ( redFsm->anyConditions() ) { out << " " << condsType << " _conds;\n" " " << WIDE_ALPH_TYPE() << " _widec;\n"; } if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " switch ( " << FSA() << "[" << vCS() << "] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " switch ( " << TA() << "[_trans] ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " switch ( " << TSA() << "[" << vCS() << "] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << CAST(transType) << " (" << ET() << "[" << vCS() << "] - 1);\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " switch ( " << EA() << "[" << vCS() << "] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/cdftable.cpp0000664000175000017500000002370413065111230013015 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdftable.h" #include "redfsm.h" #include "gendata.h" /* Determine if we should use indicies or not. */ void FTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActListId) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActListId) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &FTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &FTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &FTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &FTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FTabCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FTabCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } void FTabCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void FTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n" " int _klen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n" " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_keys;\n" " int _trans;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; out << "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " switch ( " << FSA() << "[" << vCS() << "] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); out << "_match:\n"; if ( useIndicies ) out << " _trans = " << I() << "[_trans];\n"; if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " switch ( " << TA() << "[_trans] ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " switch ( " << TSA() << "[" << vCS() << "] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " switch ( " << EA() << "[" << vCS() << "] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/cssplit.h0000664000175000017500000000322213065111230012370 00000000000000/* * Copyright 2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _SPLITCODEGEN_H #define _SPLITCODEGEN_H #include "csipgoto.h" class CSharpSplitCodeGen : public CSharpIpGotoCodeGen { public: CSharpSplitCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpIpGotoCodeGen(out) {} bool ptOutLabelUsed; std::ostream &PART_MAP(); std::ostream &EXIT_STATES( int partition ); std::ostream &PART_TRANS( int partition ); std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); void GOTO_HEADER( RedStateAp *state, bool stateInPartition ); std::ostream &STATE_GOTOS( int partition ); std::ostream &PARTITION( int partition ); std::ostream &ALL_PARTITIONS(); void writeData(); void writeExec(); void writeParts(); void setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ); void setLabelsNeeded( RedStateAp *fromState, RedTransAp *trans ); void setLabelsNeeded(); int currentPartition; }; #endif ragel-6.10/ragel/rubyfflat.h0000664000175000017500000000370213065111230012710 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RUBY_FFLATCODEGEN_H #define _RUBY_FFLATCODEGEN_H #include #include "rubyflat.h" class RubyFFlatCodeGen : public RubyFlatCodeGen { public: RubyFFlatCodeGen( ostream &out ) : RubyFlatCodeGen(out) {} protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); void GOTO( ostream &out, int gotoDest, bool inFinish ); void GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ); void CALL( ostream &out, int callDest, int targState, bool inFinish ); void CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ); void RET( ostream &out, bool inFinish ); void BREAK( ostream &out, int targState ); virtual int TO_STATE_ACTION( RedStateAp *state ); virtual int FROM_STATE_ACTION( RedStateAp *state ); virtual int EOF_ACTION( RedStateAp *state ); virtual int TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ #endif ragel-6.10/ragel/parsetree.cpp0000664000175000017500000016650013065111230013245 00000000000000/* * Copyright 2001-2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include /* Parsing. */ #include "ragel.h" #include "rlparse.h" #include "parsetree.h" using namespace std; ostream &operator<<( ostream &out, const NameRef &nameRef ); ostream &operator<<( ostream &out, const NameInst &nameInst ); /* Convert the literal string which comes in from the scanner into an array of * characters with escapes and options interpreted. Also null terminates the * string. Though this null termination should not be relied on for * interpreting literals in the parser because the string may contain \0 */ char *prepareLitString( const InputLoc &loc, const char *data, long length, long &resLen, bool &caseInsensitive ) { char *resData = new char[length+1]; caseInsensitive = false; const char *src = data + 1; const char *end = data + length - 1; while ( *end != '\'' && *end != '\"' ) { if ( *end == 'i' ) caseInsensitive = true; else { error( loc ) << "literal string '" << *end << "' option not supported" << endl; } end -= 1; } char *dest = resData; long len = 0; while ( src != end ) { if ( *src == '\\' ) { switch ( src[1] ) { case '0': dest[len++] = '\0'; break; case 'a': dest[len++] = '\a'; break; case 'b': dest[len++] = '\b'; break; case 't': dest[len++] = '\t'; break; case 'n': dest[len++] = '\n'; break; case 'v': dest[len++] = '\v'; break; case 'f': dest[len++] = '\f'; break; case 'r': dest[len++] = '\r'; break; case '\n': break; default: dest[len++] = src[1]; break; } src += 2; } else { dest[len++] = *src++; } } resLen = len; resData[resLen] = 0; return resData; } FsmAp *VarDef::walk( ParseData *pd ) { /* We enter into a new name scope. */ NameFrame nameFrame = pd->enterNameScope( true, 1 ); /* Recurse on the expression. */ FsmAp *rtnVal = machineDef->walk( pd ); /* Do the tranfer of local error actions. */ LocalErrDictEl *localErrDictEl = pd->localErrDict.find( name ); if ( localErrDictEl != 0 ) { for ( StateList::Iter state = rtnVal->stateList; state.lte(); state++ ) rtnVal->transferErrorActions( state, localErrDictEl->value ); } /* If the expression below is a join operation with multiple expressions * then it just had epsilon transisions resolved. If it is a join * with only a single expression then run the epsilon op now. */ if ( machineDef->type == MachineDef::JoinType && machineDef->join->exprList.length() == 1 ) rtnVal->epsilonOp(); /* We can now unset entry points that are not longer used. */ pd->unsetObsoleteEntries( rtnVal ); /* If the name of the variable is referenced then add the entry point to * the graph. */ if ( pd->curNameInst->numRefs > 0 ) rtnVal->setEntry( pd->curNameInst->id, rtnVal->startState ); /* Pop the name scope. */ pd->popNameScope( nameFrame ); return rtnVal; } void VarDef::makeNameTree( const InputLoc &loc, ParseData *pd ) { /* The variable definition enters a new scope. */ NameInst *prevNameInst = pd->curNameInst; pd->curNameInst = pd->addNameInst( loc, name, false ); if ( machineDef->type == MachineDef::LongestMatchType ) pd->curNameInst->isLongestMatch = true; /* Recurse. */ machineDef->makeNameTree( pd ); /* The name scope ends, pop the name instantiation. */ pd->curNameInst = prevNameInst; } void VarDef::resolveNameRefs( ParseData *pd ) { /* Entering into a new scope. */ NameFrame nameFrame = pd->enterNameScope( true, 1 ); /* Recurse. */ machineDef->resolveNameRefs( pd ); /* The name scope ends, pop the name instantiation. */ pd->popNameScope( nameFrame ); } InputLoc LongestMatchPart::getLoc() { return action != 0 ? action->loc : semiLoc; } /* * If there are any LMs then all of the following entry points must reset * tokstart: * * 1. fentry(StateRef) * 2. ftoto(StateRef), fcall(StateRef), fnext(StateRef) * 3. targt of any transition that has an fcall (the return loc). * 4. start state of all longest match routines. */ Action *LongestMatch::newAction( ParseData *pd, const InputLoc &loc, const char *name, InlineList *inlineList ) { Action *action = new Action( loc, name, inlineList, pd->nextCondId++ ); action->actionRefs.append( pd->curNameInst ); pd->actionList.append( action ); action->isLmAction = true; return action; } void LongestMatch::makeActions( ParseData *pd ) { /* Make actions that set the action id. */ for ( LmPartList::Iter lmi = *longestMatchList; lmi.lte(); lmi++ ) { /* For each part create actions for setting the match type. We need * to do this so that the actions will go into the actionIndex. */ InlineList *inlineList = new InlineList; inlineList->append( new InlineItem( lmi->getLoc(), this, lmi, InlineItem::LmSetActId ) ); char *actName = new char[50]; sprintf( actName, "store%i", lmi->longestMatchId ); lmi->setActId = newAction( pd, lmi->getLoc(), actName, inlineList ); } /* Make actions that execute the user action and restart on the last * character. */ for ( LmPartList::Iter lmi = *longestMatchList; lmi.lte(); lmi++ ) { /* For each part create actions for setting the match type. We need * to do this so that the actions will go into the actionIndex. */ InlineList *inlineList = new InlineList; inlineList->append( new InlineItem( lmi->getLoc(), this, lmi, InlineItem::LmOnLast ) ); char *actName = new char[50]; sprintf( actName, "last%i", lmi->longestMatchId ); lmi->actOnLast = newAction( pd, lmi->getLoc(), actName, inlineList ); } /* Make actions that execute the user action and restart on the next * character. These actions will set tokend themselves (it is the current * char). */ for ( LmPartList::Iter lmi = *longestMatchList; lmi.lte(); lmi++ ) { /* For each part create actions for setting the match type. We need * to do this so that the actions will go into the actionIndex. */ InlineList *inlineList = new InlineList; inlineList->append( new InlineItem( lmi->getLoc(), this, lmi, InlineItem::LmOnNext ) ); char *actName = new char[50]; sprintf( actName, "next%i", lmi->longestMatchId ); lmi->actOnNext = newAction( pd, lmi->getLoc(), actName, inlineList ); } /* Make actions that execute the user action and restart at tokend. These * actions execute some time after matching the last char. */ for ( LmPartList::Iter lmi = *longestMatchList; lmi.lte(); lmi++ ) { /* For each part create actions for setting the match type. We need * to do this so that the actions will go into the actionIndex. */ InlineList *inlineList = new InlineList; inlineList->append( new InlineItem( lmi->getLoc(), this, lmi, InlineItem::LmOnLagBehind ) ); char *actName = new char[50]; sprintf( actName, "lag%i", lmi->longestMatchId ); lmi->actLagBehind = newAction( pd, lmi->getLoc(), actName, inlineList ); } InputLoc loc; loc.line = 1; loc.col = 1; loc.fileName = "NONE"; /* Create the error action. */ InlineList *il6 = new InlineList; il6->append( new InlineItem( loc, this, 0, InlineItem::LmSwitch ) ); lmActSelect = newAction( pd, loc, "switch", il6 ); } void LongestMatch::findName( ParseData *pd ) { NameInst *nameInst = pd->curNameInst; while ( nameInst->name == 0 ) { nameInst = nameInst->parent; /* Since every machine must must have a name, we should always find a * name for the longest match. */ assert( nameInst != 0 ); } name = nameInst->name; } void LongestMatch::makeNameTree( ParseData *pd ) { /* Create an anonymous scope for the longest match. Will be used for * restarting machine after matching a token. */ NameInst *prevNameInst = pd->curNameInst; pd->curNameInst = pd->addNameInst( loc, 0, false ); /* Recurse into all parts of the longest match operator. */ for ( LmPartList::Iter lmi = *longestMatchList; lmi.lte(); lmi++ ) lmi->join->makeNameTree( pd ); /* Traverse the name tree upwards to find a name for this lm. */ findName( pd ); /* Also make the longest match's actions at this point. */ makeActions( pd ); /* The name scope ends, pop the name instantiation. */ pd->curNameInst = prevNameInst; } void LongestMatch::resolveNameRefs( ParseData *pd ) { /* The longest match gets its own name scope. */ NameFrame nameFrame = pd->enterNameScope( true, 1 ); /* Take an action reference for each longest match item and recurse. */ for ( LmPartList::Iter lmi = *longestMatchList; lmi.lte(); lmi++ ) { /* Record the reference if the item has an action. */ if ( lmi->action != 0 ) lmi->action->actionRefs.append( pd->localNameScope ); /* Recurse down the join. */ lmi->join->resolveNameRefs( pd ); } /* The name scope ends, pop the name instantiation. */ pd->popNameScope( nameFrame ); } void LongestMatch::restart( FsmAp *graph, TransAp *trans ) { StateAp *fromState = trans->fromState; graph->detachTrans( fromState, trans->toState, trans ); graph->attachTrans( fromState, graph->startState, trans ); } void LongestMatch::runLongestMatch( ParseData *pd, FsmAp *graph ) { graph->markReachableFromHereStopFinal( graph->startState ); for ( StateList::Iter ms = graph->stateList; ms.lte(); ms++ ) { if ( ms->stateBits & STB_ISMARKED ) { ms->lmItemSet.insert( 0 ); ms->stateBits &= ~ STB_ISMARKED; } } /* Transfer the first item of non-empty lmAction tables to the item sets * of the states that follow. Exclude states that have no transitions out. * This must happen on a separate pass so that on each iteration of the * next pass we have the item set entries from all lmAction tables. */ for ( StateList::Iter st = graph->stateList; st.lte(); st++ ) { for ( TransList::Iter trans = st->outList; trans.lte(); trans++ ) { if ( trans->lmActionTable.length() > 0 ) { LmActionTableEl *lmAct = trans->lmActionTable.data; StateAp *toState = trans->toState; assert( toState ); /* Can only optimize this if there are no transitions out. * Note there can be out transitions going nowhere with * actions and they too must inhibit this optimization. */ if ( toState->outList.length() > 0 ) { /* Fill the item sets. */ graph->markReachableFromHereStopFinal( toState ); for ( StateList::Iter ms = graph->stateList; ms.lte(); ms++ ) { if ( ms->stateBits & STB_ISMARKED ) { ms->lmItemSet.insert( lmAct->value ); ms->stateBits &= ~ STB_ISMARKED; } } } } } } /* The lmItem sets are now filled, telling us which longest match rules * can succeed in which states. First determine if we need to make sure * act is defaulted to zero. We need to do this if there are any states * with lmItemSet.length() > 1 and NULL is included. That is, that the * switch may get called when in fact nothing has been matched. */ int maxItemSetLength = 0; graph->markReachableFromHereStopFinal( graph->startState ); for ( StateList::Iter ms = graph->stateList; ms.lte(); ms++ ) { if ( ms->stateBits & STB_ISMARKED ) { if ( ms->lmItemSet.length() > maxItemSetLength ) maxItemSetLength = ms->lmItemSet.length(); ms->stateBits &= ~ STB_ISMARKED; } } /* The actions executed on starting to match a token. */ graph->isolateStartState(); graph->startState->toStateActionTable.setAction( pd->initTokStartOrd, pd->initTokStart ); graph->startState->fromStateActionTable.setAction( pd->setTokStartOrd, pd->setTokStart ); if ( maxItemSetLength > 1 ) { /* The longest match action switch may be called when tokens are * matched, in which case act must be initialized, there must be a * case to handle the error, and the generated machine will require an * error state. */ lmSwitchHandlesError = true; pd->lmRequiresErrorState = true; graph->startState->toStateActionTable.setAction( pd->initActIdOrd, pd->initActId ); } /* The place to store transitions to restart. It maybe possible for the * restarting to affect the searching through the graph that follows. For * now take the safe route and save the list of transitions to restart * until after all searching is done. */ Vector restartTrans; /* Set actions that do immediate token recognition, set the longest match part * id and set the token ending. */ for ( StateList::Iter st = graph->stateList; st.lte(); st++ ) { for ( TransList::Iter trans = st->outList; trans.lte(); trans++ ) { if ( trans->lmActionTable.length() > 0 ) { LmActionTableEl *lmAct = trans->lmActionTable.data; StateAp *toState = trans->toState; assert( toState ); /* Can only optimize this if there are no transitions out. * Note there can be out transitions going nowhere with * actions and they too must inhibit this optimization. */ if ( toState->outList.length() == 0 ) { /* Can execute the immediate action for the longest match * part. Redirect the action to the start state. * * NOTE: When we need to inhibit on_last due to leaving * actions the above test suffices. If the state has out * actions then it will fail because the out action will * have been transferred to an error transition, which * makes the outlist non-empty. */ trans->actionTable.setAction( lmAct->key, lmAct->value->actOnLast ); restartTrans.append( trans ); } else { /* Look for non final states that have a non-empty item * set. If these are present then we need to record the * end of the token. Also Find the highest item set * length reachable from here (excluding at transtions to * final states). */ bool nonFinalNonEmptyItemSet = false; maxItemSetLength = 0; graph->markReachableFromHereStopFinal( toState ); for ( StateList::Iter ms = graph->stateList; ms.lte(); ms++ ) { if ( ms->stateBits & STB_ISMARKED ) { if ( ms->lmItemSet.length() > 0 && !ms->isFinState() ) nonFinalNonEmptyItemSet = true; if ( ms->lmItemSet.length() > maxItemSetLength ) maxItemSetLength = ms->lmItemSet.length(); ms->stateBits &= ~ STB_ISMARKED; } } /* If there are reachable states that are not final and * have non empty item sets or that have an item set * length greater than one then we need to set tokend * because the error action that matches the token will * require it. */ if ( nonFinalNonEmptyItemSet || maxItemSetLength > 1 ) trans->actionTable.setAction( pd->setTokEndOrd, pd->setTokEnd ); /* Some states may not know which longest match item to * execute, must set it. */ if ( maxItemSetLength > 1 ) { /* There are transitions out, another match may come. */ trans->actionTable.setAction( lmAct->key, lmAct->value->setActId ); } } } } } /* Now that all graph searching is done it certainly safe set the * restarting. It may be safe above, however this must be verified. */ for ( Vector::Iter pt = restartTrans; pt.lte(); pt++ ) restart( graph, *pt ); int lmErrActionOrd = pd->curActionOrd++; /* Embed the error for recognizing a char. */ for ( StateList::Iter st = graph->stateList; st.lte(); st++ ) { if ( st->lmItemSet.length() == 1 && st->lmItemSet[0] != 0 ) { if ( st->isFinState() ) { /* On error execute the onActNext action, which knows that * the last character of the token was one back and restart. */ graph->setErrorTarget( st, graph->startState, &lmErrActionOrd, &st->lmItemSet[0]->actOnNext, 1 ); st->eofActionTable.setAction( lmErrActionOrd, st->lmItemSet[0]->actOnNext ); st->eofTarget = graph->startState; } else { graph->setErrorTarget( st, graph->startState, &lmErrActionOrd, &st->lmItemSet[0]->actLagBehind, 1 ); st->eofActionTable.setAction( lmErrActionOrd, st->lmItemSet[0]->actLagBehind ); st->eofTarget = graph->startState; } } else if ( st->lmItemSet.length() > 1 ) { /* Need to use the select. Take note of which items the select * is needed for so only the necessary actions are included. */ for ( LmItemSet::Iter plmi = st->lmItemSet; plmi.lte(); plmi++ ) { if ( *plmi != 0 ) (*plmi)->inLmSelect = true; } /* On error, execute the action select and go to the start state. */ graph->setErrorTarget( st, graph->startState, &lmErrActionOrd, &lmActSelect, 1 ); st->eofActionTable.setAction( lmErrActionOrd, lmActSelect ); st->eofTarget = graph->startState; } } /* Finally, the start state should be made final. */ graph->setFinState( graph->startState ); } void LongestMatch::transferScannerLeavingActions( FsmAp *graph ) { for ( StateList::Iter st = graph->stateList; st.lte(); st++ ) { if ( st->outActionTable.length() > 0 ) graph->setErrorActions( st, st->outActionTable ); } } FsmAp *LongestMatch::walk( ParseData *pd ) { /* The longest match has it's own name scope. */ NameFrame nameFrame = pd->enterNameScope( true, 1 ); /* Make each part of the longest match. */ FsmAp **parts = new FsmAp*[longestMatchList->length()]; LmPartList::Iter lmi = *longestMatchList; for ( int i = 0; lmi.lte(); lmi++, i++ ) { /* Create the machine and embed the setting of the longest match id. */ parts[i] = lmi->join->walk( pd ); parts[i]->longMatchAction( pd->curActionOrd++, lmi ); } /* Before we union the patterns we need to deal with leaving actions. They * are transfered to error transitions out of the final states (like local * error actions) and to eof actions. In the scanner we need to forbid * on_last for any final state that has an leaving action. */ for ( int i = 0; i < longestMatchList->length(); i++ ) transferScannerLeavingActions( parts[i] ); /* Union machines one and up with machine zero. The grammar dictates that * there will always be at least one part. */ FsmAp *rtnVal = parts[0]; for ( int i = 1; i < longestMatchList->length(); i++ ) { rtnVal->unionOp( parts[i] ); afterOpMinimize( rtnVal ); } runLongestMatch( pd, rtnVal ); /* Pop the name scope. */ pd->popNameScope( nameFrame ); delete[] parts; return rtnVal; } FsmAp *MachineDef::walk( ParseData *pd ) { FsmAp *rtnVal = 0; switch ( type ) { case JoinType: rtnVal = join->walk( pd ); break; case LongestMatchType: rtnVal = longestMatch->walk( pd ); break; case LengthDefType: condData->lastCondKey.increment(); rtnVal = new FsmAp(); rtnVal->concatFsm( condData->lastCondKey ); break; } return rtnVal; } void MachineDef::makeNameTree( ParseData *pd ) { switch ( type ) { case JoinType: join->makeNameTree( pd ); break; case LongestMatchType: longestMatch->makeNameTree( pd ); break; case LengthDefType: break; } } void MachineDef::resolveNameRefs( ParseData *pd ) { switch ( type ) { case JoinType: join->resolveNameRefs( pd ); break; case LongestMatchType: longestMatch->resolveNameRefs( pd ); break; case LengthDefType: break; } } /* Construct with a location and the first expression. */ Join::Join( const InputLoc &loc, Expression *expr ) : loc(loc) { exprList.append( expr ); } /* Construct with a location and the first expression. */ Join::Join( Expression *expr ) { exprList.append( expr ); } /* Walk an expression node. */ FsmAp *Join::walk( ParseData *pd ) { if ( exprList.length() > 1 ) return walkJoin( pd ); else return exprList.head->walk( pd ); } /* There is a list of expressions to join. */ FsmAp *Join::walkJoin( ParseData *pd ) { /* We enter into a new name scope. */ NameFrame nameFrame = pd->enterNameScope( true, 1 ); /* Evaluate the machines. */ FsmAp **fsms = new FsmAp*[exprList.length()]; ExprList::Iter expr = exprList; for ( int e = 0; e < exprList.length(); e++, expr++ ) fsms[e] = expr->walk( pd ); /* Get the start and final names. Final is * guaranteed to exist, start is not. */ NameInst *startName = pd->curNameInst->start; NameInst *finalName = pd->curNameInst->final; int startId = -1; if ( startName != 0 ) { /* Take note that there was an implicit link to the start machine. */ pd->localNameScope->referencedNames.append( startName ); startId = startName->id; } /* A final id of -1 indicates there is no epsilon that references the * final state, therefor do not create one or set an entry point to it. */ int finalId = -1; if ( finalName->numRefs > 0 ) finalId = finalName->id; /* Join machines 1 and up onto machine 0. */ FsmAp *retFsm = fsms[0]; retFsm->joinOp( startId, finalId, fsms+1, exprList.length()-1 ); /* We can now unset entry points that are not longer used. */ pd->unsetObsoleteEntries( retFsm ); /* Pop the name scope. */ pd->popNameScope( nameFrame ); delete[] fsms; return retFsm; } void Join::makeNameTree( ParseData *pd ) { if ( exprList.length() > 1 ) { /* Create the new anonymous scope. */ NameInst *prevNameInst = pd->curNameInst; pd->curNameInst = pd->addNameInst( loc, 0, false ); /* Join scopes need an implicit "final" target. */ pd->curNameInst->final = new NameInst( InputLoc(), pd->curNameInst, "final", pd->nextNameId++, false ); /* Recurse into all expressions in the list. */ for ( ExprList::Iter expr = exprList; expr.lte(); expr++ ) expr->makeNameTree( pd ); /* The name scope ends, pop the name instantiation. */ pd->curNameInst = prevNameInst; } else { /* Recurse into the single expression. */ exprList.head->makeNameTree( pd ); } } void Join::resolveNameRefs( ParseData *pd ) { /* Branch on whether or not there is to be a join. */ if ( exprList.length() > 1 ) { /* The variable definition enters a new scope. */ NameFrame nameFrame = pd->enterNameScope( true, 1 ); /* The join scope must contain a start label. */ NameSet resolved = pd->resolvePart( pd->localNameScope, "start", true ); if ( resolved.length() > 0 ) { /* Take the first. */ pd->curNameInst->start = resolved[0]; if ( resolved.length() > 1 ) { /* Complain about the multiple references. */ error(loc) << "join operation has multiple start labels" << endl; errorStateLabels( resolved ); } } /* Make sure there is a start label. */ if ( pd->curNameInst->start != 0 ) { /* There is an implicit reference to start name. */ pd->curNameInst->start->numRefs += 1; } else { /* No start label. */ error(loc) << "join operation has no start label" << endl; } /* Recurse into all expressions in the list. */ for ( ExprList::Iter expr = exprList; expr.lte(); expr++ ) expr->resolveNameRefs( pd ); /* The name scope ends, pop the name instantiation. */ pd->popNameScope( nameFrame ); } else { /* Recurse into the single expression. */ exprList.head->resolveNameRefs( pd ); } } /* Clean up after an expression node. */ Expression::~Expression() { switch ( type ) { case OrType: case IntersectType: case SubtractType: case StrongSubtractType: delete expression; delete term; break; case TermType: delete term; break; case BuiltinType: break; } } /* Evaluate a single expression node. */ FsmAp *Expression::walk( ParseData *pd, bool lastInSeq ) { FsmAp *rtnVal = 0; switch ( type ) { case OrType: { /* Evaluate the expression. */ rtnVal = expression->walk( pd, false ); /* Evaluate the term. */ FsmAp *rhs = term->walk( pd ); /* Perform union. */ rtnVal->unionOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case IntersectType: { /* Evaluate the expression. */ rtnVal = expression->walk( pd ); /* Evaluate the term. */ FsmAp *rhs = term->walk( pd ); /* Perform intersection. */ rtnVal->intersectOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case SubtractType: { /* Evaluate the expression. */ rtnVal = expression->walk( pd ); /* Evaluate the term. */ FsmAp *rhs = term->walk( pd ); /* Perform subtraction. */ rtnVal->subtractOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case StrongSubtractType: { /* Evaluate the expression. */ rtnVal = expression->walk( pd ); /* Evaluate the term and pad it with any* machines. */ FsmAp *rhs = dotStarFsm( pd ); FsmAp *termFsm = term->walk( pd ); FsmAp *trailAnyStar = dotStarFsm( pd ); rhs->concatOp( termFsm ); rhs->concatOp( trailAnyStar ); /* Perform subtraction. */ rtnVal->subtractOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case TermType: { /* Return result of the term. */ rtnVal = term->walk( pd ); break; } case BuiltinType: { /* Duplicate the builtin. */ rtnVal = makeBuiltin( builtin, pd ); break; } } return rtnVal; } void Expression::makeNameTree( ParseData *pd ) { switch ( type ) { case OrType: case IntersectType: case SubtractType: case StrongSubtractType: expression->makeNameTree( pd ); term->makeNameTree( pd ); break; case TermType: term->makeNameTree( pd ); break; case BuiltinType: break; } } void Expression::resolveNameRefs( ParseData *pd ) { switch ( type ) { case OrType: case IntersectType: case SubtractType: case StrongSubtractType: expression->resolveNameRefs( pd ); term->resolveNameRefs( pd ); break; case TermType: term->resolveNameRefs( pd ); break; case BuiltinType: break; } } /* Clean up after a term node. */ Term::~Term() { switch ( type ) { case ConcatType: case RightStartType: case RightFinishType: case LeftType: delete term; delete factorWithAug; break; case FactorWithAugType: delete factorWithAug; break; } } /* Evaluate a term node. */ FsmAp *Term::walk( ParseData *pd, bool lastInSeq ) { FsmAp *rtnVal = 0; switch ( type ) { case ConcatType: { /* Evaluate the Term. */ rtnVal = term->walk( pd, false ); /* Evaluate the FactorWithRep. */ FsmAp *rhs = factorWithAug->walk( pd ); /* Perform concatenation. */ rtnVal->concatOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case RightStartType: { /* Evaluate the Term. */ rtnVal = term->walk( pd ); /* Evaluate the FactorWithRep. */ FsmAp *rhs = factorWithAug->walk( pd ); /* Set up the priority descriptors. The left machine gets the * lower priority where as the right get the higher start priority. */ priorDescs[0].key = pd->nextPriorKey++; priorDescs[0].priority = 0; rtnVal->allTransPrior( pd->curPriorOrd++, &priorDescs[0] ); /* The start transitions of the right machine gets the higher * priority. Use the same unique key. */ priorDescs[1].key = priorDescs[0].key; priorDescs[1].priority = 1; rhs->startFsmPrior( pd->curPriorOrd++, &priorDescs[1] ); /* Perform concatenation. */ rtnVal->concatOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case RightFinishType: { /* Evaluate the Term. */ rtnVal = term->walk( pd ); /* Evaluate the FactorWithRep. */ FsmAp *rhs = factorWithAug->walk( pd ); /* Set up the priority descriptors. The left machine gets the * lower priority where as the finishing transitions to the right * get the higher priority. */ priorDescs[0].key = pd->nextPriorKey++; priorDescs[0].priority = 0; rtnVal->allTransPrior( pd->curPriorOrd++, &priorDescs[0] ); /* The finishing transitions of the right machine get the higher * priority. Use the same unique key. */ priorDescs[1].key = priorDescs[0].key; priorDescs[1].priority = 1; rhs->finishFsmPrior( pd->curPriorOrd++, &priorDescs[1] ); /* If the right machine's start state is final we need to guard * against the left machine persisting by moving through the empty * string. */ if ( rhs->startState->isFinState() ) { rhs->startState->outPriorTable.setPrior( pd->curPriorOrd++, &priorDescs[1] ); } /* Perform concatenation. */ rtnVal->concatOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case LeftType: { /* Evaluate the Term. */ rtnVal = term->walk( pd ); /* Evaluate the FactorWithRep. */ FsmAp *rhs = factorWithAug->walk( pd ); /* Set up the priority descriptors. The left machine gets the * higher priority. */ priorDescs[0].key = pd->nextPriorKey++; priorDescs[0].priority = 1; rtnVal->allTransPrior( pd->curPriorOrd++, &priorDescs[0] ); /* The right machine gets the lower priority. We cannot use * allTransPrior here in case the start state of the right machine * is final. It would allow the right machine thread to run along * with the left if just passing through the start state. Using * startFsmPrior prevents this. */ priorDescs[1].key = priorDescs[0].key; priorDescs[1].priority = 0; rhs->startFsmPrior( pd->curPriorOrd++, &priorDescs[1] ); /* Perform concatenation. */ rtnVal->concatOp( rhs ); afterOpMinimize( rtnVal, lastInSeq ); break; } case FactorWithAugType: { rtnVal = factorWithAug->walk( pd ); break; } } return rtnVal; } void Term::makeNameTree( ParseData *pd ) { switch ( type ) { case ConcatType: case RightStartType: case RightFinishType: case LeftType: term->makeNameTree( pd ); factorWithAug->makeNameTree( pd ); break; case FactorWithAugType: factorWithAug->makeNameTree( pd ); break; } } void Term::resolveNameRefs( ParseData *pd ) { switch ( type ) { case ConcatType: case RightStartType: case RightFinishType: case LeftType: term->resolveNameRefs( pd ); factorWithAug->resolveNameRefs( pd ); break; case FactorWithAugType: factorWithAug->resolveNameRefs( pd ); break; } } /* Clean up after a factor with augmentation node. */ FactorWithAug::~FactorWithAug() { delete factorWithRep; /* Walk the vector of parser actions, deleting function names. */ /* Clean up priority descriptors. */ if ( priorDescs != 0 ) delete[] priorDescs; } void FactorWithAug::assignActions( ParseData *pd, FsmAp *graph, int *actionOrd ) { /* Assign actions. */ for ( int i = 0; i < actions.length(); i++ ) { switch ( actions[i].type ) { /* Transition actions. */ case at_start: graph->startFsmAction( actionOrd[i], actions[i].action ); afterOpMinimize( graph ); break; case at_all: graph->allTransAction( actionOrd[i], actions[i].action ); break; case at_finish: graph->finishFsmAction( actionOrd[i], actions[i].action ); break; case at_leave: graph->leaveFsmAction( actionOrd[i], actions[i].action ); break; /* Global error actions. */ case at_start_gbl_error: graph->startErrorAction( actionOrd[i], actions[i].action, 0 ); afterOpMinimize( graph ); break; case at_all_gbl_error: graph->allErrorAction( actionOrd[i], actions[i].action, 0 ); break; case at_final_gbl_error: graph->finalErrorAction( actionOrd[i], actions[i].action, 0 ); break; case at_not_start_gbl_error: graph->notStartErrorAction( actionOrd[i], actions[i].action, 0 ); break; case at_not_final_gbl_error: graph->notFinalErrorAction( actionOrd[i], actions[i].action, 0 ); break; case at_middle_gbl_error: graph->middleErrorAction( actionOrd[i], actions[i].action, 0 ); break; /* Local error actions. */ case at_start_local_error: graph->startErrorAction( actionOrd[i], actions[i].action, actions[i].localErrKey ); afterOpMinimize( graph ); break; case at_all_local_error: graph->allErrorAction( actionOrd[i], actions[i].action, actions[i].localErrKey ); break; case at_final_local_error: graph->finalErrorAction( actionOrd[i], actions[i].action, actions[i].localErrKey ); break; case at_not_start_local_error: graph->notStartErrorAction( actionOrd[i], actions[i].action, actions[i].localErrKey ); break; case at_not_final_local_error: graph->notFinalErrorAction( actionOrd[i], actions[i].action, actions[i].localErrKey ); break; case at_middle_local_error: graph->middleErrorAction( actionOrd[i], actions[i].action, actions[i].localErrKey ); break; /* EOF actions. */ case at_start_eof: graph->startEOFAction( actionOrd[i], actions[i].action ); afterOpMinimize( graph ); break; case at_all_eof: graph->allEOFAction( actionOrd[i], actions[i].action ); break; case at_final_eof: graph->finalEOFAction( actionOrd[i], actions[i].action ); break; case at_not_start_eof: graph->notStartEOFAction( actionOrd[i], actions[i].action ); break; case at_not_final_eof: graph->notFinalEOFAction( actionOrd[i], actions[i].action ); break; case at_middle_eof: graph->middleEOFAction( actionOrd[i], actions[i].action ); break; /* To State Actions. */ case at_start_to_state: graph->startToStateAction( actionOrd[i], actions[i].action ); afterOpMinimize( graph ); break; case at_all_to_state: graph->allToStateAction( actionOrd[i], actions[i].action ); break; case at_final_to_state: graph->finalToStateAction( actionOrd[i], actions[i].action ); break; case at_not_start_to_state: graph->notStartToStateAction( actionOrd[i], actions[i].action ); break; case at_not_final_to_state: graph->notFinalToStateAction( actionOrd[i], actions[i].action ); break; case at_middle_to_state: graph->middleToStateAction( actionOrd[i], actions[i].action ); break; /* From State Actions. */ case at_start_from_state: graph->startFromStateAction( actionOrd[i], actions[i].action ); afterOpMinimize( graph ); break; case at_all_from_state: graph->allFromStateAction( actionOrd[i], actions[i].action ); break; case at_final_from_state: graph->finalFromStateAction( actionOrd[i], actions[i].action ); break; case at_not_start_from_state: graph->notStartFromStateAction( actionOrd[i], actions[i].action ); break; case at_not_final_from_state: graph->notFinalFromStateAction( actionOrd[i], actions[i].action ); break; case at_middle_from_state: graph->middleFromStateAction( actionOrd[i], actions[i].action ); break; /* Remaining cases, prevented by the parser. */ default: assert( false ); break; } } } void FactorWithAug::assignPriorities( FsmAp *graph, int *priorOrd ) { /* Assign priorities. */ for ( int i = 0; i < priorityAugs.length(); i++ ) { switch ( priorityAugs[i].type ) { case at_start: graph->startFsmPrior( priorOrd[i], &priorDescs[i]); /* Start fsm priorities are a special case that may require * minimization afterwards. */ afterOpMinimize( graph ); break; case at_all: graph->allTransPrior( priorOrd[i], &priorDescs[i] ); break; case at_finish: graph->finishFsmPrior( priorOrd[i], &priorDescs[i] ); break; case at_leave: graph->leaveFsmPrior( priorOrd[i], &priorDescs[i] ); break; default: /* Parser Prevents this case. */ break; } } } void FactorWithAug::assignConditions( FsmAp *graph ) { for ( int i = 0; i < conditions.length(); i++ ) { switch ( conditions[i].type ) { /* Transition actions. */ case at_start: graph->startFsmCondition( conditions[i].action, conditions[i].sense ); afterOpMinimize( graph ); break; case at_all: graph->allTransCondition( conditions[i].action, conditions[i].sense ); break; case at_leave: graph->leaveFsmCondition( conditions[i].action, conditions[i].sense ); break; default: break; } } } /* Evaluate a factor with augmentation node. */ FsmAp *FactorWithAug::walk( ParseData *pd ) { /* Enter into the scopes created for the labels. */ NameFrame nameFrame = pd->enterNameScope( false, labels.length() ); /* Make the array of function orderings. */ int *actionOrd = 0; if ( actions.length() > 0 ) actionOrd = new int[actions.length()]; /* First walk the list of actions, assigning order to all starting * actions. */ for ( int i = 0; i < actions.length(); i++ ) { if ( actions[i].type == at_start || actions[i].type == at_start_gbl_error || actions[i].type == at_start_local_error || actions[i].type == at_start_to_state || actions[i].type == at_start_from_state || actions[i].type == at_start_eof ) actionOrd[i] = pd->curActionOrd++; } /* Evaluate the factor with repetition. */ FsmAp *rtnVal = factorWithRep->walk( pd ); /* Compute the remaining action orderings. */ for ( int i = 0; i < actions.length(); i++ ) { if ( actions[i].type != at_start && actions[i].type != at_start_gbl_error && actions[i].type != at_start_local_error && actions[i].type != at_start_to_state && actions[i].type != at_start_from_state && actions[i].type != at_start_eof ) actionOrd[i] = pd->curActionOrd++; } /* Embed conditions. */ assignConditions( rtnVal ); /* Embed actions. */ assignActions( pd, rtnVal , actionOrd ); /* Make the array of priority orderings. Orderings are local to this walk * of the factor with augmentation. */ int *priorOrd = 0; if ( priorityAugs.length() > 0 ) priorOrd = new int[priorityAugs.length()]; /* Walk all priorities, assigning the priority ordering. */ for ( int i = 0; i < priorityAugs.length(); i++ ) priorOrd[i] = pd->curPriorOrd++; /* If the priority descriptors have not been made, make them now. Make * priority descriptors for each priority asignment that will be passed to * the fsm. Used to keep track of the key, value and used bit. */ if ( priorDescs == 0 && priorityAugs.length() > 0 ) { priorDescs = new PriorDesc[priorityAugs.length()]; for ( int i = 0; i < priorityAugs.length(); i++ ) { /* Init the prior descriptor for the priority setting. */ priorDescs[i].key = priorityAugs[i].priorKey; priorDescs[i].priority = priorityAugs[i].priorValue; } } /* Assign priorities into the machine. */ assignPriorities( rtnVal, priorOrd ); /* Assign epsilon transitions. */ for ( int e = 0; e < epsilonLinks.length(); e++ ) { /* Get the name, which may not exist. If it doesn't then silently * ignore it because an error has already been reported. */ NameInst *epTarg = pd->epsilonResolvedLinks[pd->nextEpsilonResolvedLink++]; if ( epTarg != 0 ) { /* Make the epsilon transitions. */ rtnVal->epsilonTrans( epTarg->id ); /* Note that we have made a link to the name. */ pd->localNameScope->referencedNames.append( epTarg ); } } /* Set entry points for labels. */ if ( labels.length() > 0 ) { /* Pop the names. */ pd->resetNameScope( nameFrame ); /* Make labels that are referenced into entry points. */ for ( int i = 0; i < labels.length(); i++ ) { pd->enterNameScope( false, 1 ); /* Will always be found. */ NameInst *name = pd->curNameInst; /* If the name is referenced then set the entry point. */ if ( name->numRefs > 0 ) rtnVal->setEntry( name->id, rtnVal->startState ); } pd->popNameScope( nameFrame ); } if ( priorOrd != 0 ) delete[] priorOrd; if ( actionOrd != 0 ) delete[] actionOrd; return rtnVal; } void FactorWithAug::makeNameTree( ParseData *pd ) { /* Add the labels to the tree of instantiated names. Each label * makes a new scope. */ NameInst *prevNameInst = pd->curNameInst; for ( int i = 0; i < labels.length(); i++ ) pd->curNameInst = pd->addNameInst( labels[i].loc, labels[i].data, true ); /* Recurse, then pop the names. */ factorWithRep->makeNameTree( pd ); pd->curNameInst = prevNameInst; } void FactorWithAug::resolveNameRefs( ParseData *pd ) { /* Enter into the name scope created by any labels. */ NameFrame nameFrame = pd->enterNameScope( false, labels.length() ); /* Note action references. */ for ( int i = 0; i < actions.length(); i++ ) actions[i].action->actionRefs.append( pd->localNameScope ); /* Recurse first. IMPORTANT: we must do the exact same traversal as when * the tree is constructed. */ factorWithRep->resolveNameRefs( pd ); /* Resolve epsilon transitions. */ for ( int ep = 0; ep < epsilonLinks.length(); ep++ ) { /* Get the link. */ EpsilonLink &link = epsilonLinks[ep]; NameInst *resolvedName = 0; if ( link.target.length() == 1 && strcmp( link.target.data[0], "final" ) == 0 ) { /* Epsilon drawn to an implicit final state. An implicit final is * only available in join operations. */ resolvedName = pd->localNameScope->final; } else { /* Do an search for the name. */ NameSet resolved; pd->resolveFrom( resolved, pd->localNameScope, link.target, 0 ); if ( resolved.length() > 0 ) { /* Take the first one. */ resolvedName = resolved[0]; if ( resolved.length() > 1 ) { /* Complain about the multiple references. */ error(link.loc) << "state reference " << link.target << " resolves to multiple entry points" << endl; errorStateLabels( resolved ); } } } /* This is tricky, we stuff resolved epsilon transitions into one long * vector in the parse data structure. Since the name resolution and * graph generation both do identical walks of the parse tree we * should always find the link resolutions in the right place. */ pd->epsilonResolvedLinks.append( resolvedName ); if ( resolvedName != 0 ) { /* Found the name, bump of the reference count on it. */ resolvedName->numRefs += 1; } else { /* Complain, no recovery action, the epsilon op will ignore any * epsilon transitions whose names did not resolve. */ error(link.loc) << "could not resolve label " << link.target << endl; } } if ( labels.length() > 0 ) pd->popNameScope( nameFrame ); } /* Clean up after a factor with repetition node. */ FactorWithRep::~FactorWithRep() { switch ( type ) { case StarType: case StarStarType: case OptionalType: case PlusType: case ExactType: case MaxType: case MinType: case RangeType: delete factorWithRep; break; case FactorWithNegType: delete factorWithNeg; break; } } /* Evaluate a factor with repetition node. */ FsmAp *FactorWithRep::walk( ParseData *pd ) { FsmAp *retFsm = 0; switch ( type ) { case StarType: { /* Evaluate the FactorWithRep. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying kleene star to a machine that " "accepts zero length word" << endl; retFsm->unsetFinState( retFsm->startState ); } /* Shift over the start action orders then do the kleene star. */ pd->curActionOrd += retFsm->shiftStartActionOrder( pd->curActionOrd ); retFsm->starOp( ); afterOpMinimize( retFsm ); break; } case StarStarType: { /* Evaluate the FactorWithRep. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying kleene star to a machine that " "accepts zero length word" << endl; } /* Set up the prior descs. All gets priority one, whereas leaving gets * priority zero. Make a unique key so that these priorities don't * interfere with any priorities set by the user. */ priorDescs[0].key = pd->nextPriorKey++; priorDescs[0].priority = 1; retFsm->allTransPrior( pd->curPriorOrd++, &priorDescs[0] ); /* Leaveing gets priority 0. Use same unique key. */ priorDescs[1].key = priorDescs[0].key; priorDescs[1].priority = 0; retFsm->leaveFsmPrior( pd->curPriorOrd++, &priorDescs[1] ); /* Shift over the start action orders then do the kleene star. */ pd->curActionOrd += retFsm->shiftStartActionOrder( pd->curActionOrd ); retFsm->starOp( ); afterOpMinimize( retFsm ); break; } case OptionalType: { /* Make the null fsm. */ FsmAp *nu = new FsmAp(); nu->lambdaFsm( ); /* Evaluate the FactorWithRep. */ retFsm = factorWithRep->walk( pd ); /* Perform the question operator. */ retFsm->unionOp( nu ); afterOpMinimize( retFsm ); break; } case PlusType: { /* Evaluate the FactorWithRep. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying plus operator to a machine that " "accepts zero length word" << endl; } /* Need a duplicated for the star end. */ FsmAp *dup = new FsmAp( *retFsm ); /* The start func orders need to be shifted before doing the star. */ pd->curActionOrd += dup->shiftStartActionOrder( pd->curActionOrd ); /* Star the duplicate. */ dup->starOp( ); afterOpMinimize( dup ); retFsm->concatOp( dup ); afterOpMinimize( retFsm ); break; } case ExactType: { /* Get an int from the repetition amount. */ if ( lowerRep == 0 ) { /* No copies. Don't need to evaluate the factorWithRep. * This Defeats the purpose so give a warning. */ warning(loc) << "exactly zero repetitions results " "in the null machine" << endl; retFsm = new FsmAp(); retFsm->lambdaFsm(); } else { /* Evaluate the first FactorWithRep. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying repetition to a machine that " "accepts zero length word" << endl; } /* The start func orders need to be shifted before doing the * repetition. */ pd->curActionOrd += retFsm->shiftStartActionOrder( pd->curActionOrd ); /* Do the repetition on the machine. Already guarded against n == 0 */ retFsm->repeatOp( lowerRep ); afterOpMinimize( retFsm ); } break; } case MaxType: { /* Get an int from the repetition amount. */ if ( upperRep == 0 ) { /* No copies. Don't need to evaluate the factorWithRep. * This Defeats the purpose so give a warning. */ warning(loc) << "max zero repetitions results " "in the null machine" << endl; retFsm = new FsmAp(); retFsm->lambdaFsm(); } else { /* Evaluate the first FactorWithRep. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying max repetition to a machine that " "accepts zero length word" << endl; } /* The start func orders need to be shifted before doing the * repetition. */ pd->curActionOrd += retFsm->shiftStartActionOrder( pd->curActionOrd ); /* Do the repetition on the machine. Already guarded against n == 0 */ retFsm->optionalRepeatOp( upperRep ); afterOpMinimize( retFsm ); } break; } case MinType: { /* Evaluate the repeated machine. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying min repetition to a machine that " "accepts zero length word" << endl; } /* The start func orders need to be shifted before doing the repetition * and the kleene star. */ pd->curActionOrd += retFsm->shiftStartActionOrder( pd->curActionOrd ); if ( lowerRep == 0 ) { /* Acts just like a star op on the machine to return. */ retFsm->starOp( ); afterOpMinimize( retFsm ); } else { /* Take a duplicate for the plus. */ FsmAp *dup = new FsmAp( *retFsm ); /* Do repetition on the first half. */ retFsm->repeatOp( lowerRep ); afterOpMinimize( retFsm ); /* Star the duplicate. */ dup->starOp( ); afterOpMinimize( dup ); /* Tak on the kleene star. */ retFsm->concatOp( dup ); afterOpMinimize( retFsm ); } break; } case RangeType: { /* Check for bogus range. */ if ( upperRep - lowerRep < 0 ) { error(loc) << "invalid range repetition" << endl; /* Return null machine as recovery. */ retFsm = new FsmAp(); retFsm->lambdaFsm(); } else if ( lowerRep == 0 && upperRep == 0 ) { /* No copies. Don't need to evaluate the factorWithRep. This * defeats the purpose so give a warning. */ warning(loc) << "zero to zero repetitions results " "in the null machine" << endl; retFsm = new FsmAp(); retFsm->lambdaFsm(); } else { /* Now need to evaluate the repeated machine. */ retFsm = factorWithRep->walk( pd ); if ( retFsm->startState->isFinState() ) { warning(loc) << "applying range repetition to a machine that " "accepts zero length word" << endl; } /* The start func orders need to be shifted before doing both kinds * of repetition. */ pd->curActionOrd += retFsm->shiftStartActionOrder( pd->curActionOrd ); if ( lowerRep == 0 ) { /* Just doing max repetition. Already guarded against n == 0. */ retFsm->optionalRepeatOp( upperRep ); afterOpMinimize( retFsm ); } else if ( lowerRep == upperRep ) { /* Just doing exact repetition. Already guarded against n == 0. */ retFsm->repeatOp( lowerRep ); afterOpMinimize( retFsm ); } else { /* This is the case that 0 < lowerRep < upperRep. Take a * duplicate for the optional repeat. */ FsmAp *dup = new FsmAp( *retFsm ); /* Do repetition on the first half. */ retFsm->repeatOp( lowerRep ); afterOpMinimize( retFsm ); /* Do optional repetition on the second half. */ dup->optionalRepeatOp( upperRep - lowerRep ); afterOpMinimize( dup ); /* Tak on the duplicate machine. */ retFsm->concatOp( dup ); afterOpMinimize( retFsm ); } } break; } case FactorWithNegType: { /* Evaluate the Factor. Pass it up. */ retFsm = factorWithNeg->walk( pd ); break; }} return retFsm; } void FactorWithRep::makeNameTree( ParseData *pd ) { switch ( type ) { case StarType: case StarStarType: case OptionalType: case PlusType: case ExactType: case MaxType: case MinType: case RangeType: factorWithRep->makeNameTree( pd ); break; case FactorWithNegType: factorWithNeg->makeNameTree( pd ); break; } } void FactorWithRep::resolveNameRefs( ParseData *pd ) { switch ( type ) { case StarType: case StarStarType: case OptionalType: case PlusType: case ExactType: case MaxType: case MinType: case RangeType: factorWithRep->resolveNameRefs( pd ); break; case FactorWithNegType: factorWithNeg->resolveNameRefs( pd ); break; } } /* Clean up after a factor with negation node. */ FactorWithNeg::~FactorWithNeg() { switch ( type ) { case NegateType: case CharNegateType: delete factorWithNeg; break; case FactorType: delete factor; break; } } /* Evaluate a factor with negation node. */ FsmAp *FactorWithNeg::walk( ParseData *pd ) { FsmAp *retFsm = 0; switch ( type ) { case NegateType: { /* Evaluate the factorWithNeg. */ FsmAp *toNegate = factorWithNeg->walk( pd ); /* Negation is subtract from dot-star. */ retFsm = dotStarFsm( pd ); retFsm->subtractOp( toNegate ); afterOpMinimize( retFsm ); break; } case CharNegateType: { /* Evaluate the factorWithNeg. */ FsmAp *toNegate = factorWithNeg->walk( pd ); /* CharNegation is subtract from dot. */ retFsm = dotFsm( pd ); retFsm->subtractOp( toNegate ); afterOpMinimize( retFsm ); break; } case FactorType: { /* Evaluate the Factor. Pass it up. */ retFsm = factor->walk( pd ); break; }} return retFsm; } void FactorWithNeg::makeNameTree( ParseData *pd ) { switch ( type ) { case NegateType: case CharNegateType: factorWithNeg->makeNameTree( pd ); break; case FactorType: factor->makeNameTree( pd ); break; } } void FactorWithNeg::resolveNameRefs( ParseData *pd ) { switch ( type ) { case NegateType: case CharNegateType: factorWithNeg->resolveNameRefs( pd ); break; case FactorType: factor->resolveNameRefs( pd ); break; } } /* Clean up after a factor node. */ Factor::~Factor() { switch ( type ) { case LiteralType: delete literal; break; case RangeType: delete range; break; case OrExprType: delete reItem; break; case RegExprType: delete regExpr; break; case ReferenceType: break; case ParenType: delete join; break; case LongestMatchType: delete longestMatch; break; } } /* Evaluate a factor node. */ FsmAp *Factor::walk( ParseData *pd ) { FsmAp *rtnVal = 0; switch ( type ) { case LiteralType: rtnVal = literal->walk( pd ); break; case RangeType: rtnVal = range->walk( pd ); break; case OrExprType: rtnVal = reItem->walk( pd, 0 ); break; case RegExprType: rtnVal = regExpr->walk( pd, 0 ); break; case ReferenceType: rtnVal = varDef->walk( pd ); break; case ParenType: rtnVal = join->walk( pd ); break; case LongestMatchType: rtnVal = longestMatch->walk( pd ); break; } return rtnVal; } void Factor::makeNameTree( ParseData *pd ) { switch ( type ) { case LiteralType: case RangeType: case OrExprType: case RegExprType: break; case ReferenceType: varDef->makeNameTree( loc, pd ); break; case ParenType: join->makeNameTree( pd ); break; case LongestMatchType: longestMatch->makeNameTree( pd ); break; } } void Factor::resolveNameRefs( ParseData *pd ) { switch ( type ) { case LiteralType: case RangeType: case OrExprType: case RegExprType: break; case ReferenceType: varDef->resolveNameRefs( pd ); break; case ParenType: join->resolveNameRefs( pd ); break; case LongestMatchType: longestMatch->resolveNameRefs( pd ); break; } } /* Clean up a range object. Must delete the two literals. */ Range::~Range() { delete lowerLit; delete upperLit; } /* Evaluate a range. Gets the lower an upper key and makes an fsm range. */ FsmAp *Range::walk( ParseData *pd ) { /* Construct and verify the suitability of the lower end of the range. */ FsmAp *lowerFsm = lowerLit->walk( pd ); if ( !lowerFsm->checkSingleCharMachine() ) { error(lowerLit->token.loc) << "bad range lower end, must be a single character" << endl; } /* Construct and verify the upper end. */ FsmAp *upperFsm = upperLit->walk( pd ); if ( !upperFsm->checkSingleCharMachine() ) { error(upperLit->token.loc) << "bad range upper end, must be a single character" << endl; } /* Grab the keys from the machines, then delete them. */ Key lowKey = lowerFsm->startState->outList.head->lowKey; Key highKey = upperFsm->startState->outList.head->lowKey; delete lowerFsm; delete upperFsm; /* Validate the range. */ if ( lowKey > highKey ) { /* Recover by setting upper to lower; */ error(lowerLit->token.loc) << "lower end of range is greater then upper end" << endl; highKey = lowKey; } /* Return the range now that it is validated. */ FsmAp *retFsm = new FsmAp(); retFsm->rangeFsm( lowKey, highKey ); return retFsm; } /* Evaluate a literal object. */ FsmAp *Literal::walk( ParseData *pd ) { /* FsmAp to return, is the alphabet signed. */ FsmAp *rtnVal = 0; switch ( type ) { case Number: { /* Make the fsm key in int format. */ Key fsmKey = makeFsmKeyNum( token.data, token.loc, pd ); /* Make the new machine. */ rtnVal = new FsmAp(); rtnVal->concatFsm( fsmKey ); break; } case LitString: { /* Make the array of keys in int format. */ long length; bool caseInsensitive; char *data = prepareLitString( token.loc, token.data, token.length, length, caseInsensitive ); Key *arr = new Key[length]; makeFsmKeyArray( arr, data, length, pd ); /* Make the new machine. */ rtnVal = new FsmAp(); if ( caseInsensitive ) rtnVal->concatFsmCI( arr, length ); else rtnVal->concatFsm( arr, length ); delete[] data; delete[] arr; break; }} return rtnVal; } /* Clean up after a regular expression object. */ RegExpr::~RegExpr() { switch ( type ) { case RecurseItem: delete regExpr; delete item; break; case Empty: break; } } /* Evaluate a regular expression object. */ FsmAp *RegExpr::walk( ParseData *pd, RegExpr *rootRegex ) { /* This is the root regex, pass down a pointer to this. */ if ( rootRegex == 0 ) rootRegex = this; FsmAp *rtnVal = 0; switch ( type ) { case RecurseItem: { /* Walk both items. */ rtnVal = regExpr->walk( pd, rootRegex ); FsmAp *fsm2 = item->walk( pd, rootRegex ); rtnVal->concatOp( fsm2 ); break; } case Empty: { rtnVal = new FsmAp(); rtnVal->lambdaFsm(); break; } } return rtnVal; } /* Clean up after an item in a regular expression. */ ReItem::~ReItem() { switch ( type ) { case Data: case Dot: break; case OrBlock: case NegOrBlock: delete orBlock; break; } } /* Evaluate a regular expression object. */ FsmAp *ReItem::walk( ParseData *pd, RegExpr *rootRegex ) { /* The fsm to return, is the alphabet signed? */ FsmAp *rtnVal = 0; switch ( type ) { case Data: { /* Move the data into an integer array and make a concat fsm. */ Key *arr = new Key[token.length]; makeFsmKeyArray( arr, token.data, token.length, pd ); /* Make the concat fsm. */ rtnVal = new FsmAp(); if ( rootRegex != 0 && rootRegex->caseInsensitive ) rtnVal->concatFsmCI( arr, token.length ); else rtnVal->concatFsm( arr, token.length ); delete[] arr; break; } case Dot: { /* Make the dot fsm. */ rtnVal = dotFsm( pd ); break; } case OrBlock: { /* Get the or block and minmize it. */ rtnVal = orBlock->walk( pd, rootRegex ); if ( rtnVal == 0 ) { rtnVal = new FsmAp(); rtnVal->lambdaFsm(); } rtnVal->minimizePartition2(); break; } case NegOrBlock: { /* Get the or block and minimize it. */ FsmAp *fsm = orBlock->walk( pd, rootRegex ); fsm->minimizePartition2(); /* Make a dot fsm and subtract from it. */ rtnVal = dotFsm( pd ); rtnVal->subtractOp( fsm ); rtnVal->minimizePartition2(); break; } } /* If the item is followed by a star, then apply the star op. */ if ( star ) { if ( rtnVal->startState->isFinState() ) { warning(loc) << "applying kleene star to a machine that " "accepts zero length word" << endl; } rtnVal->starOp(); rtnVal->minimizePartition2(); } return rtnVal; } /* Clean up after an or block of a regular expression. */ ReOrBlock::~ReOrBlock() { switch ( type ) { case RecurseItem: delete orBlock; delete item; break; case Empty: break; } } /* Evaluate an or block of a regular expression. */ FsmAp *ReOrBlock::walk( ParseData *pd, RegExpr *rootRegex ) { FsmAp *rtnVal = 0; switch ( type ) { case RecurseItem: { /* Evaluate the two fsm. */ FsmAp *fsm1 = orBlock->walk( pd, rootRegex ); FsmAp *fsm2 = item->walk( pd, rootRegex ); if ( fsm1 == 0 ) rtnVal = fsm2; else { fsm1->unionOp( fsm2 ); rtnVal = fsm1; } break; } case Empty: { rtnVal = 0; break; } } return rtnVal;; } /* Evaluate an or block item of a regular expression. */ FsmAp *ReOrItem::walk( ParseData *pd, RegExpr *rootRegex ) { /* The return value, is the alphabet signed? */ FsmAp *rtnVal = 0; switch ( type ) { case Data: { /* Make the or machine. */ rtnVal = new FsmAp(); /* Put the or data into an array of ints. Note that we find unique * keys. Duplicates are silently ignored. The alternative would be to * issue warning or an error but since we can't with [a0-9a] or 'a' | * 'a' don't bother here. */ KeySet keySet; makeFsmUniqueKeyArray( keySet, token.data, token.length, rootRegex != 0 ? rootRegex->caseInsensitive : false, pd ); /* Run the or operator. */ rtnVal->orFsm( keySet.data, keySet.length() ); break; } case Range: { /* Make the upper and lower keys. */ Key lowKey = makeFsmKeyChar( lower, pd ); Key highKey = makeFsmKeyChar( upper, pd ); /* Validate the range. */ if ( lowKey > highKey ) { /* Recover by setting upper to lower; */ error(loc) << "lower end of range is greater then upper end" << endl; highKey = lowKey; } /* Make the range machine. */ rtnVal = new FsmAp(); rtnVal->rangeFsm( lowKey, highKey ); if ( rootRegex != 0 && rootRegex->caseInsensitive ) { if ( lowKey <= 'Z' && 'A' <= highKey ) { Key otherLow = lowKey < 'A' ? Key('A') : lowKey; Key otherHigh = 'Z' < highKey ? Key('Z') : highKey; otherLow = 'a' + ( otherLow - 'A' ); otherHigh = 'a' + ( otherHigh - 'A' ); FsmAp *otherRange = new FsmAp(); otherRange->rangeFsm( otherLow, otherHigh ); rtnVal->unionOp( otherRange ); rtnVal->minimizePartition2(); } else if ( lowKey <= 'z' && 'a' <= highKey ) { Key otherLow = lowKey < 'a' ? Key('a') : lowKey; Key otherHigh = 'z' < highKey ? Key('z') : highKey; otherLow = 'A' + ( otherLow - 'a' ); otherHigh = 'A' + ( otherHigh - 'a' ); FsmAp *otherRange = new FsmAp(); otherRange->rangeFsm( otherLow, otherHigh ); rtnVal->unionOp( otherRange ); rtnVal->minimizePartition2(); } } break; }} return rtnVal; } ragel-6.10/ragel/rubyflat.h0000664000175000017500000000533613065111230012547 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RUBY_FLATCODEGEN_H #define _RUBY_FLATCODEGEN_H #include #include "rubycodegen.h" using std::string; using std::ostream; /* * FlatCodeGen */ class RubyFlatCodeGen : public RubyCodeGen { public: RubyFlatCodeGen( ostream &out ) : RubyCodeGen(out) {}; virtual ~RubyFlatCodeGen() {} protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &FLAT_INDEX_OFFSET(); std::ostream &KEY_SPANS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); void LOCATE_TRANS(); std::ostream &COND_INDEX_OFFSET(); void COND_TRANSLATE(); std::ostream &CONDS(); std::ostream &COND_KEYS(); std::ostream &COND_KEY_SPANS(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState ); virtual int TO_STATE_ACTION( RedStateAp *state ); virtual int FROM_STATE_ACTION( RedStateAp *state ); virtual int EOF_ACTION( RedStateAp *state ); virtual int TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; #endif /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/mlgoto.cpp0000664000175000017500000005560113065111230012553 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "mlgoto.h" #include "redfsm.h" #include "bstmap.h" #include "gendata.h" /* Emit the goto to take for a given transition. */ std::ostream &OCamlGotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { out << TABS(level) << "tr" << trans->id << " ()"; return out; } std::ostream &OCamlGotoCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlGotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlGotoCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, true ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlGotoCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } void OCamlGotoCodeGen::GOTO_HEADER( RedStateAp *state ) { /* Label the state. */ out << "| " << state->id << " ->\n"; } void OCamlGotoCodeGen::emitSingleSwitch( RedStateAp *state ) { /* Load up the singles. */ int numSingles = state->outSingle.length(); RedTransEl *data = state->outSingle.data; if ( numSingles == 1 ) { /* If there is a single single key then write it out as an if. */ out << "\tif " << GET_WIDE_KEY(state) << " = " << KEY(data[0].lowKey) << " then\n\t\t"; /* Virtual function for writing the target of the transition. */ TRANS_GOTO(data[0].value, 0) << " else\n"; } else if ( numSingles > 1 ) { /* Write out single keys in a switch if there is more than one. */ out << "\tmatch " << GET_WIDE_KEY(state) << " with\n"; /* Write out the single indicies. */ for ( int j = 0; j < numSingles; j++ ) { out << "\t\t| " << ALPHA_KEY(data[j].lowKey) << " -> "; TRANS_GOTO(data[j].value, 0) << "\n"; } out << "\t\t| _ ->\n"; } } void OCamlGotoCodeGen::emitRangeBSearch( RedStateAp *state, int level, int low, int high, RedTransAp* def) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; RedTransEl *data = state->outRange.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid].lowKey == keyOps->minKey; bool limitHigh = data[mid].highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if " << GET_WIDE_KEY(state) << " < " << KEY(data[mid].lowKey) << " then begin\n"; emitRangeBSearch( state, level+1, low, mid-1, def ); out << TABS(level) << " end else if " << GET_WIDE_KEY(state) << " > " << KEY(data[mid].highKey) << " then begin\n"; emitRangeBSearch( state, level+1, mid+1, high, def ); out << TABS(level) << " end else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if " << GET_WIDE_KEY(state) << " < " << KEY(data[mid].lowKey) << " then begin\n"; emitRangeBSearch( state, level+1, low, mid-1, def ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << " end else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << " end else if " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " then\n"; TRANS_GOTO(data[mid].value, level+1) << "\n" << TABS(level) << "else\n"; TRANS_GOTO(def, level+1) << "\n"; } } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if " << GET_WIDE_KEY(state) << " > " << KEY(data[mid].highKey) << " then begin\n"; emitRangeBSearch( state, level+1, mid+1, high, def ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << " end else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << " end else if " << GET_WIDE_KEY(state) << " >= " << KEY(data[mid].lowKey) << " then\n"; TRANS_GOTO(data[mid].value, level+1) << "\n" << TABS(level) << "else\n"; TRANS_GOTO(def, level+1) << "\n"; } } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if " << KEY(data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " && " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " then\n"; TRANS_GOTO(data[mid].value, level+1) << "\n" << TABS(level) << "else\n"; TRANS_GOTO(def, level+1) << "\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " then\n"; TRANS_GOTO(data[mid].value, level+1) << "\n" << TABS(level) << "else\n"; TRANS_GOTO(def, level+1) << "\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if " << KEY(data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " then\n"; TRANS_GOTO(data[mid].value, level+1) << "\n" << TABS(level) << "else\n"; TRANS_GOTO(def, level+1) << "\n"; } else { /* Both high and low are at the limit. No tests to do. */ TRANS_GOTO(data[mid].value, level+1) << "\n"; } } } void OCamlGotoCodeGen::STATE_GOTO_ERROR() { /* Label the state and bail immediately. */ outLabelUsed = true; RedStateAp *state = redFsm->errState; out << "| " << state->id << " ->\n"; out << " do_out ()\n"; } void OCamlGotoCodeGen::COND_TRANSLATE( GenStateCond *stateCond, int level ) { GenCondSpace *condSpace = stateCond->condSpace; out << TABS(level) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(level) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } } void OCamlGotoCodeGen::emitCondBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; GenStateCond **data = state->stateCondVect.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid]->lowKey == keyOps->minKey; bool limitHigh = data[mid]->highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if ( " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " ) {\n"; emitCondBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "} else if ( " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " ) {\n"; emitCondBSearch( state, level+1, mid+1, high ); out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if ( " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " ) {\n"; emitCondBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { out << TABS(level) << "} else if ( " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if ( " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " ) {\n"; emitCondBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { out << TABS(level) << "} else if ( " << GET_KEY() << " >= " << KEY(data[mid]->lowKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " && " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if ( " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " )\n {"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { /* Both high and low are at the limit. No tests to do. */ COND_TRANSLATE(data[mid], level); } } } std::ostream &OCamlGotoCodeGen::STATE_GOTOS() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st == redFsm->errState ) STATE_GOTO_ERROR(); else { /* Writing code above state gotos. */ GOTO_HEADER( st ); out << "\tbegin\n"; if ( st->stateCondVect.length() > 0 ) { out << " _widec = " << GET_KEY() << ";\n"; emitCondBSearch( st, 1, 0, st->stateCondVect.length() - 1 ); } /* Try singles. */ if ( st->outSingle.length() > 0 ) emitSingleSwitch( st ); /* Default case is to binary search for the ranges, if that fails then */ if ( st->outRange.length() > 0 ) emitRangeBSearch( st, 1, 0, st->outRange.length() - 1, st->defTrans ); else /* Write the default transition. */ TRANS_GOTO( st->defTrans, 1 ) << "\n"; out << "\tend\n"; } } return out; } std::ostream &OCamlGotoCodeGen::TRANSITIONS() { /* Emit any transitions that have functions and that go to * this state. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Write the label for the transition so it can be jumped to. */ out << " and tr" << trans->id << " () = "; /* Destination state. */ if ( trans->action != 0 && trans->action->anyCurStateRef() ) out << "_ps = " << vCS() << ";"; out << vCS() << " <- " << trans->targ->id << "; "; if ( trans->action != 0 ) { /* Write out the transition func. */ out << "f" << trans->action->actListId << " ()\n"; } else { /* No code to execute, just loop around. */ out << "do_again ()\n"; } } return out; } std::ostream &OCamlGotoCodeGen::EXEC_FUNCS() { /* Make labels that set acts and jump to execFuncs. Loop func indicies. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { out << " and f" << redAct->actListId << " () = " << "state.acts <- " << itoa( redAct->location+1 ) << "; " "execFuncs ()\n"; } } out << "\n" "and execFuncs () =\n" " state.nacts <- " << AT( A(), POST_INCR( "state.acts") ) << ";\n" " begin try while " << POST_DECR("state.nacts") << " > 0 do\n" " match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " done with Goto_again -> () end;\n" " do_again ()\n"; return out; } unsigned int OCamlGotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; return act; } unsigned int OCamlGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; return act; } unsigned int OCamlGotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; return act; } std::ostream &OCamlGotoCodeGen::TO_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = TO_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ARR_SEP(); if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &OCamlGotoCodeGen::FROM_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = FROM_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ARR_SEP(); if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &OCamlGotoCodeGen::EOF_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = EOF_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ARR_SEP(); if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &OCamlGotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << "\t\t| " << st->id << " -> "; /* Write the goto func. */ out << "f" << st->eofAction->actListId << " ()\n"; } } return out; } void OCamlGotoCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "begin " << vCS() << " <- " << gotoDest << "; " << CTRL_FLOW() << "raise Goto_again end"; } void OCamlGotoCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "begin " << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << "raise Goto_again end"; } void OCamlGotoCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void OCamlGotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void OCamlGotoCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " <- " << nextDest << ";"; } void OCamlGotoCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void OCamlGotoCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin " << AT( STACK(), POST_INCR(TOP()) ) << " <- " << vCS() << "; "; ret << vCS() << " <- " << callDest << "; " << CTRL_FLOW() << "raise Goto_again end "; if ( prePushExpr != 0 ) ret << "end"; } void OCamlGotoCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin " << AT(STACK(), POST_INCR(TOP()) ) << " <- " << vCS() << "; " << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << "); " << CTRL_FLOW() << "raise Goto_again end "; if ( prePushExpr != 0 ) ret << "end"; } void OCamlGotoCodeGen::RET( ostream &ret, bool inFinish ) { ret << "begin " << vCS() << " <- " << AT(STACK(), PRE_DECR(TOP()) ) << "; "; if ( postPopExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "end "; } ret << CTRL_FLOW() << "raise Goto_again end"; } void OCamlGotoCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; ret << "begin " << P() << " <- " << P() << " + 1; " << CTRL_FLOW() << "raise Goto_out end"; } void OCamlGotoCodeGen::writeData() { if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); out << "type " << TYPE_STATE() << " = { mutable acts : " << ARRAY_TYPE(redFsm->maxActionLoc) << " ; mutable nacts : " << ARRAY_TYPE(redFsm->maxActArrItem) << "; }" << TOP_SEP(); out << "exception Goto_again" << TOP_SEP(); } void OCamlGotoCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " begin\n"; // if ( redFsm->anyRegCurStateRef() ) // out << " int _ps = 0;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " let state = { acts = 0; nacts = 0; } in\n"; } // if ( redFsm->anyConditions() ) // out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; out << "\n"; out << " let rec do_start () =\n"; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " = " << PE() << " then\n" " do_test_eof ()\n" "\telse\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " = " << redFsm->errState->id << " then\n" " do_out ()\n" "\telse\n"; } out << "\tdo_resume ()\n"; out << "and do_resume () =\n"; if ( redFsm->anyFromStateActions() ) { out << " state.acts <- " << AT( FSA(), vCS() ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n" " done;\n" "\n"; } out << " begin match " << vCS() << " with\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " end\n" "\n"; TRANSITIONS() << "\n"; if ( redFsm->anyRegActions() ) EXEC_FUNCS() << "\n"; // if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || // redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "\tand do_again () =\n"; if ( redFsm->anyToStateActions() ) { out << " state.acts <- " << AT( TSA(), vCS() ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n" " done;\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " match " << vCS() << " with\n" "\t| " << redFsm->errState->id << " -> do_out ()\n" "\t| _ ->\n"; } out << "\t" << P() << " <- " << P() << " + 1;\n"; if ( !noEnd ) { out << " if " << P() << " <> " << PE() << " then\n" " do_resume ()\n" "\telse do_test_eof ()\n"; } else { out << " do_resume ()\n"; } // if ( testEofUsed ) out << "and do_test_eof () =\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " = " << vEOF() << " then\n" " begin\n"; if ( redFsm->anyEofTrans() ) { out << " match " << vCS() << " with\n"; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " | " << st->id << " -> tr" << st->eofTrans->id << " ()\n"; } out << "\t| _ -> ();\n"; } if ( redFsm->anyEofActions() ) { out << " let __acts = ref " << AT( EA(), vCS() ) << " in\n" " let __nacts = ref " << AT( A(), "!__acts" ) << " in\n" " incr __acts;\n" " begin try while !__nacts > 0 do\n" " decr __nacts;\n" " begin match " << AT( A(), POST_INCR("__acts.contents") ) << " with\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" " done with Goto_again -> do_again () end;\n"; } out << " end\n" "\n"; } else { out << "\t()\n"; } if ( outLabelUsed ) out << " and do_out () = ()\n"; out << "\tin do_start ()\n"; out << " end;\n"; } ragel-6.10/ragel/cdfflat.h0000664000175000017500000000421013065111230012310 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDFFLAT_H #define _CDFFLAT_H #include #include "cdflat.h" /* Forwards. */ struct CodeGenData; /* * FFlatCodeGen */ class FFlatCodeGen : public FlatCodeGen { protected: FFlatCodeGen( ostream &out ) : FsmCodeGen(out), FlatCodeGen(out) {} std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; /* * CFFlatCodeGen */ struct CFFlatCodeGen : public FFlatCodeGen, public CCodeGen { CFFlatCodeGen( ostream &out ) : FsmCodeGen(out), FFlatCodeGen(out), CCodeGen(out) {} }; /* * DFFlatCodeGen */ struct DFFlatCodeGen : public FFlatCodeGen, public DCodeGen { DFFlatCodeGen( ostream &out ) : FsmCodeGen(out), FFlatCodeGen(out), DCodeGen(out) {} }; /* * D2FFlatCodeGen */ struct D2FFlatCodeGen : public FFlatCodeGen, public D2CodeGen { D2FFlatCodeGen( ostream &out ) : FsmCodeGen(out), FFlatCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/goftable.h0000664000175000017500000000325713065111230012502 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOFTABLE_H #define _GOFTABLE_H #include #include "gotable.h" /* Forwards. */ struct CodeGenData; /* * GoFTabCode */ class GoFTabCodeGen : public GoTabCodeGen { public: GoFTabCodeGen( ostream &out ) : GoTabCodeGen(out) {} protected: std::ostream &TO_STATE_ACTION_SWITCH( int level ); std::ostream &FROM_STATE_ACTION_SWITCH( int level ); std::ostream &EOF_ACTION_SWITCH( int level ); std::ostream &ACTION_SWITCH( int level ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); virtual void calcIndexSize(); }; #endif ragel-6.10/ragel/rlparse.h0000664000175000017500000001232413065122655012377 00000000000000/* Automatically generated by Kelbt from "rlparse.kh". * * Parts of this file are copied from Kelbt source covered by the GNU * GPL. As a special exception, you may use the parts of this file copied * from Kelbt source without restriction. The remainder is derived from * "rlparse.kh" and inherits the copyright status of that file. */ #line 1 "rlparse.kh" /* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RLPARSE_H #define _RLPARSE_H #include #include "avltree.h" #include "parsedata.h" /* Import scanner tokens. */ #define IMP_Word 128 #define IMP_Literal 129 #define IMP_UInt 130 #define IMP_Define 131 /* This is used for tracking the include files/machine pairs. */ struct IncludeHistoryItem { IncludeHistoryItem( const char *fileName, const char *sectionName ) : fileName(fileName), sectionName(sectionName) {} const char *fileName; const char *sectionName; }; typedef Vector IncludeHistory; struct Parser { #line 102 "rlparse.kh" #line 63 "rlparse.h" struct Parser_Block *block; struct Parser_LangEl *freshEl; int freshPos; struct Parser_LangEl *pool; int numRetry; int numNodes; struct Parser_LangEl *stackTop; struct Parser_LangEl *lastFinal; int errCount; int curs; #line 105 "rlparse.kh" void init(); int parseLangEl( int type, const Token *token ); Parser( const char *fileName, char *sectionName, InputLoc §ionLoc ) : sectionName(sectionName) { pd = new ParseData( fileName, sectionName, sectionLoc ); exportContext.append( false ); includeHistory.append( IncludeHistoryItem( fileName, sectionName ) ); } int token( InputLoc &loc, int tokId, char *tokstart, int toklen ); void tryMachineDef( InputLoc &loc, char *name, MachineDef *machineDef, bool isInstance ); /* Report an error encountered by the parser. */ ostream &parse_error( int tokId, Token &token ); ParseData *pd; /* The name of the root section, this does not change during an include. */ char *sectionName; NameRef nameRef; NameRefList nameRefList; Vector exportContext; IncludeHistory includeHistory; Parser *prev, *next; }; #line 109 "rlparse.h" #define TK_Word 128 #define TK_Literal 129 #define TK_Number 130 #define TK_EndSection 131 #define TK_UInt 132 #define TK_Hex 133 #define TK_DotDot 134 #define TK_ColonGt 135 #define TK_ColonGtGt 136 #define TK_LtColon 137 #define TK_Arrow 138 #define TK_DoubleArrow 139 #define TK_StarStar 140 #define TK_ColonEquals 141 #define TK_NameSep 142 #define TK_BarStar 143 #define TK_DashDash 144 #define TK_StartCond 145 #define TK_AllCond 146 #define TK_LeavingCond 147 #define TK_Middle 148 #define TK_StartGblError 149 #define TK_AllGblError 150 #define TK_FinalGblError 151 #define TK_NotFinalGblError 152 #define TK_NotStartGblError 153 #define TK_MiddleGblError 154 #define TK_StartLocalError 155 #define TK_AllLocalError 156 #define TK_FinalLocalError 157 #define TK_NotFinalLocalError 158 #define TK_NotStartLocalError 159 #define TK_MiddleLocalError 160 #define TK_StartEOF 161 #define TK_AllEOF 162 #define TK_FinalEOF 163 #define TK_NotFinalEOF 164 #define TK_NotStartEOF 165 #define TK_MiddleEOF 166 #define TK_StartToState 167 #define TK_AllToState 168 #define TK_FinalToState 169 #define TK_NotFinalToState 170 #define TK_NotStartToState 171 #define TK_MiddleToState 172 #define TK_StartFromState 173 #define TK_AllFromState 174 #define TK_FinalFromState 175 #define TK_NotFinalFromState 176 #define TK_NotStartFromState 177 #define TK_MiddleFromState 178 #define RE_Slash 179 #define RE_SqOpen 180 #define RE_SqOpenNeg 181 #define RE_SqClose 182 #define RE_Dot 183 #define RE_Star 184 #define RE_Dash 185 #define RE_Char 186 #define IL_WhiteSpace 187 #define IL_Comment 188 #define IL_Literal 189 #define IL_Symbol 190 #define KW_Machine 191 #define KW_Include 192 #define KW_Import 193 #define KW_Write 194 #define KW_Action 195 #define KW_AlphType 196 #define KW_Range 197 #define KW_GetKey 198 #define KW_InWhen 199 #define KW_When 200 #define KW_OutWhen 201 #define KW_Eof 202 #define KW_Err 203 #define KW_Lerr 204 #define KW_To 205 #define KW_From 206 #define KW_Export 207 #define KW_PrePush 208 #define KW_PostPop 209 #define KW_Length 210 #define KW_Break 211 #define KW_Exec 212 #define KW_Hold 213 #define KW_PChar 214 #define KW_Char 215 #define KW_Goto 216 #define KW_Call 217 #define KW_Ret 218 #define KW_CurState 219 #define KW_TargState 220 #define KW_Entry 221 #define KW_Next 222 #define KW_Variable 223 #define KW_Access 224 #define Parser_tk_eof 225 #line 140 "rlparse.kh" #endif ragel-6.10/ragel/cssplit.cpp0000664000175000017500000003234413065111230012732 00000000000000/* * Copyright 2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cssplit.h" #include "gendata.h" #include using std::ostream; using std::ios; using std::endl; /* Emit the goto to take for a given transition. */ std::ostream &CSharpSplitCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { if ( trans->targ->partition == currentPartition ) { if ( trans->action != 0 ) { /* Go to the transition which will go to the state. */ out << TABS(level) << "goto tr" << trans->id << ";"; } else { /* Go directly to the target state. */ out << TABS(level) << "goto st" << trans->targ->id << ";"; } } else { if ( trans->action != 0 ) { /* Go to the transition which will go to the state. */ out << TABS(level) << "goto ptr" << trans->id << ";"; trans->partitionBoundary = true; } else { /* Go directly to the target state. */ out << TABS(level) << "goto pst" << trans->targ->id << ";"; trans->targ->partitionBoundary = true; } } return out; } /* Called from before writing the gotos for each state. */ void CSharpSplitCodeGen::GOTO_HEADER( RedStateAp *state, bool stateInPartition ) { bool anyWritten = IN_TRANS_ACTIONS( state ); if ( state->labelNeeded ) out << "st" << state->id << ":\n"; if ( state->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->toStateAction->key; item.lte(); item++ ) ACTION( out, item->value, state->id, false ); } /* Advance and test buffer pos. */ if ( state->labelNeeded ) { if ( !noEnd ) { out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _out" << state->id << ";\n"; } else { out << " " << P() << " += 1;\n"; } } /* Give the state a switch case. */ out << "case " << state->id << ":\n"; if ( state->fromStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->fromStateAction->key; item.lte(); item++ ) ACTION( out, item->value, state->id, false ); } if ( anyWritten ) genLineDirective( out ); /* Record the prev state if necessary. */ if ( state->anyRegCurStateRef() ) out << " _ps = " << state->id << ";\n"; } std::ostream &CSharpSplitCodeGen::STATE_GOTOS( int partition ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partition == partition ) { if ( st == redFsm->errState ) STATE_GOTO_ERROR(); else { /* We call into the base of the goto which calls back into us * using virtual functions. Set the current partition rather * than coding parameter passing throughout. */ currentPartition = partition; /* Writing code above state gotos. */ GOTO_HEADER( st, st->partition == partition ); if ( st->stateCondVect.length() > 0 ) { out << " _widec = " << GET_KEY() << ";\n"; emitCondBSearch( st, 1, 0, st->stateCondVect.length() - 1 ); } /* Try singles. */ if ( st->outSingle.length() > 0 ) emitSingleSwitch( st ); /* Default case is to binary search for the ranges, if that fails then */ if ( st->outRange.length() > 0 ) emitRangeBSearch( st, 1, 0, st->outRange.length() - 1 ); /* Write the default transition. */ TRANS_GOTO( st->defTrans, 1 ) << "\n"; } } } return out; } std::ostream &CSharpSplitCodeGen::PART_TRANS( int partition ) { for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { if ( trans->partitionBoundary ) { out << "ptr" << trans->id << ":\n"; if ( trans->action != 0 ) { /* If the action contains a next, then we must preload the current * state since the action may or may not set it. */ if ( trans->action->anyNextStmt() ) out << " " << vCS() << " = " << trans->targ->id << ";\n"; /* Write each action in the list. */ for ( GenActionTable::Iter item = trans->action->key; item.lte(); item++ ) ACTION( out, item->value, trans->targ->id, false ); } out << " goto pst" << trans->targ->id << ";\n"; trans->targ->partitionBoundary = true; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partitionBoundary ) { out << " pst" << st->id << ":\n" " " << vCS() << " = " << st->id << ";\n"; if ( st->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ for ( GenActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) ACTION( out, item->value, st->id, false ); genLineDirective( out ); } ptOutLabelUsed = true; out << " goto _pt_out; \n"; } } return out; } std::ostream &CSharpSplitCodeGen::EXIT_STATES( int partition ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partition == partition && st->outNeeded ) { outLabelUsed = true; out << " _out" << st->id << ": " << vCS() << " = " << st->id << "; goto _out; \n"; } } return out; } std::ostream &CSharpSplitCodeGen::PARTITION( int partition ) { outLabelUsed = false; ptOutLabelUsed = false; /* Initialize the partition boundaries, which get set during the writing * of states. After the state writing we will */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->partitionBoundary = false; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->partitionBoundary = false; out << " " << ALPH_TYPE() << " *p = *_pp, *pe = *_ppe;\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( useAgainLabel() ) { out << " goto _resume;\n" "\n" "_again:\n" " switch ( " << vCS() << " ) {\n"; AGAIN_CASES() << " default: break;\n" " }\n" "\n"; if ( !noEnd ) { outLabelUsed = true; out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _out;\n"; } else { out << " " << P() << " += 1;\n"; } out << "_resume:\n"; } out << " switch ( " << vCS() << " )\n {\n"; STATE_GOTOS( partition ); SWITCH_DEFAULT() << " }\n"; PART_TRANS( partition ); EXIT_STATES( partition ); if ( outLabelUsed ) { out << "\n" " _out:\n" " *_pp = p;\n" " *_ppe = pe;\n" " return 0;\n"; } if ( ptOutLabelUsed ) { out << "\n" " _pt_out:\n" " *_pp = p;\n" " *_ppe = pe;\n" " return 1;\n"; } return out; } std::ostream &CSharpSplitCodeGen::PART_MAP() { int *partMap = new int[redFsm->stateList.length()]; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) partMap[st->id] = st->partition; out << "\t"; int totalItem = 0; for ( int i = 0; i < redFsm->stateList.length(); i++ ) { out << partMap[i]; if ( i != redFsm->stateList.length() - 1 ) { out << ", "; if ( ++totalItem % IALL == 0 ) out << "\n\t"; } } delete[] partMap; return out; } void CSharpSplitCodeGen::writeData() { out << "const int " << START() << " = " << START_STATE_ID() << ";\n" "\n"; if ( !noFinal ) { out << "const int " << FIRST_FINAL() << " = " << FIRST_FINAL_STATE() << ";\n" "\n"; } if ( !noError ) { out << "const int " << ERROR() << " = " << ERROR_STATE() << ";\n" "\n"; } OPEN_ARRAY( ARRAY_TYPE(numSplitPartitions), PM() ); PART_MAP(); CLOSE_ARRAY() << "\n"; for ( int p = 0; p < redFsm->nParts; p++ ) { out << "int partition" << p << "( " << ALPH_TYPE() << " **_pp, " << ALPH_TYPE() << " **_ppe, struct " << FSM_NAME() << " *fsm );\n"; } out << "\n"; } std::ostream &CSharpSplitCodeGen::ALL_PARTITIONS() { /* compute the format string. */ int width = 0, high = redFsm->nParts - 1; while ( high > 0 ) { width++; high /= 10; } assert( width <= 8 ); char suffFormat[] = "_%6.6d.c"; suffFormat[2] = suffFormat[4] = ( '0' + width ); for ( int p = 0; p < redFsm->nParts; p++ ) { char suffix[10]; sprintf( suffix, suffFormat, p ); const char *fn = fileNameFromStem( sourceFileName, suffix ); const char *include = fileNameFromStem( sourceFileName, ".h" ); /* Create the filter on the output and open it. */ output_filter *partFilter = new output_filter( fn ); partFilter->open( fn, ios::out|ios::trunc ); if ( !partFilter->is_open() ) { error() << "error opening " << fn << " for writing" << endl; exit(1); } /* Attach the new file to the output stream. */ std::streambuf *prev_rdbuf = out.rdbuf( partFilter ); out << "#include \"" << include << "\"\n" "int partition" << p << "( " << ALPH_TYPE() << " **_pp, " << ALPH_TYPE() << " **_ppe, struct " << FSM_NAME() << " *fsm )\n" "{\n"; PARTITION( p ) << "}\n\n"; out.flush(); /* Fix the output stream. */ out.rdbuf( prev_rdbuf ); } return out; } void CSharpSplitCodeGen::writeExec() { /* Must set labels immediately before writing because we may depend on the * noend write option. */ setLabelsNeeded(); out << " {\n" " int _stat = 0;\n"; if ( !noEnd ) { out << " if ( " << P() << " == " << PE() << " )\n" " goto _out;\n"; } out << " goto _resume;\n"; /* In this reentry, to-state actions have already been executed on the * partition-switch exit from the last partition. */ out << "_reenter:\n"; if ( !noEnd ) { out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _out;\n"; } else { out << " " << P() << " += 1;\n"; } out << "_resume:\n"; out << " switch ( " << PM() << "[" << vCS() << "] ) {\n"; for ( int p = 0; p < redFsm->nParts; p++ ) { out << " case " << p << ":\n" " _stat = partition" << p << "( &p, &pe, fsm );\n" " break;\n"; } out << " }\n" " if ( _stat )\n" " goto _reenter;\n"; if ( !noEnd ) out << " _out: {}\n"; out << " }\n"; ALL_PARTITIONS(); } void CSharpSplitCodeGen::setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: { /* In split code gen we only need labels for transitions across * partitions. */ if ( fromState->partition == item->targState->partition ){ /* Mark the target as needing a label. */ item->targState->labelNeeded = true; } break; } default: break; } if ( item->children != 0 ) setLabelsNeeded( fromState, item->children ); } } void CSharpSplitCodeGen::setLabelsNeeded( RedStateAp *fromState, RedTransAp *trans ) { /* In the split code gen we don't need labels for transitions across * partitions. */ if ( fromState->partition == trans->targ->partition ) { /* If there is no action with a next statement, then the label will be * needed. */ trans->labelNeeded = true; if ( trans->action == 0 || !trans->action->anyNextStmt() ) trans->targ->labelNeeded = true; } /* Need labels for states that have goto or calls in action code * invoked on characters (ie, not from out action code). */ if ( trans->action != 0 ) { /* Loop the actions. */ for ( GenActionTable::Iter act = trans->action->key; act.lte(); act++ ) { /* Get the action and walk it's tree. */ setLabelsNeeded( fromState, act->value->inlineList ); } } } /* Set up labelNeeded flag for each state. */ void CSharpSplitCodeGen::setLabelsNeeded() { /* If we use the _again label, then we the _again switch, which uses all * labels. */ if ( useAgainLabel() ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = true; } else { /* Do not use all labels by default, init all labelNeeded vars to false. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = false; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->labelNeeded = false; /* Walk all transitions and set only those that have targs. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); for ( RedTransList::Iter tel = st->outSingle; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); if ( st->defTrans != 0 ) setLabelsNeeded( st, st->defTrans ); } } if ( !noEnd ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->outNeeded = st->labelNeeded; } else { if ( redFsm->errState != 0 ) redFsm->errState->outNeeded = true; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Any state with a transition in that has a break will need an * out label. */ if ( trans->action != 0 && trans->action->anyBreakStmt() ) trans->targ->outNeeded = true; } } } ragel-6.10/ragel/mlcodegen.cpp0000664000175000017500000004227513065111230013212 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "mlcodegen.h" #include "redfsm.h" #include "gendata.h" #include #include #include #include using std::ostream; using std::ostringstream; using std::string; using std::cerr; using std::endl; using std::istream; using std::ifstream; using std::ostream; using std::ios; using std::cin; using std::cout; using std::cerr; using std::endl; void ocamlLineDirective( ostream &out, const char *fileName, int line ) { if ( noLineDirectives ) return; /* Write the line info for to the input file. */ out << "# " << line << " \""; for ( const char *pc = fileName; *pc != 0; pc++ ) { if ( *pc == '\\' || *pc == '"' ) out << "\\"; out << *pc; } out << "\"\n"; } void OCamlCodeGen::genLineDirective( ostream &out ) { std::streambuf *sbuf = out.rdbuf(); output_filter *filter = static_cast(sbuf); ocamlLineDirective( out, filter->fileName, filter->line + 1 ); } /* Init code gen with in parameters. */ OCamlCodeGen::OCamlCodeGen( ostream &out ) : CodeGenData(out) { } unsigned int OCamlCodeGen::arrayTypeSize( unsigned long maxVal ) { long long maxValLL = (long long) maxVal; HostType *arrayType = keyOps->typeSubsumes( maxValLL ); assert( arrayType != 0 ); return arrayType->size; } string OCamlCodeGen::ARRAY_TYPE( unsigned long maxVal ) { return ARRAY_TYPE( maxVal, false ); } string OCamlCodeGen::ARRAY_TYPE( unsigned long maxVal, bool forceSigned ) { long long maxValLL = (long long) maxVal; HostType *arrayType; if (forceSigned) arrayType = keyOps->typeSubsumes(true, maxValLL); else arrayType = keyOps->typeSubsumes( maxValLL ); assert( arrayType != 0 ); string ret = arrayType->data1; if ( arrayType->data2 != 0 ) { ret += " "; ret += arrayType->data2; } return ret; } /* Write out the fsm name. */ string OCamlCodeGen::FSM_NAME() { return fsmName; } /* Emit the offset of the start state as a decimal integer. */ string OCamlCodeGen::START_STATE_ID() { ostringstream ret; ret << redFsm->startState->id; return ret.str(); }; /* Write out the array of actions. */ std::ostream &OCamlCodeGen::ACTIONS_ARRAY() { out << "\t0; "; int totalActions = 1; for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ out << act->key.length() << ARR_SEP(); /* Put in a line break every 8 */ if ( totalActions++ % 8 == 7 ) out << "\n\t"; for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) { out << item->value->actionId; if ( ! (act.last() && item.last()) ) out << ARR_SEP(); /* Put in a line break every 8 */ if ( totalActions++ % 8 == 7 ) out << "\n\t"; } } out << "\n"; return out; } /* string OCamlCodeGen::ACCESS() { ostringstream ret; if ( accessExpr != 0 ) INLINE_LIST( ret, accessExpr, 0, false ); return ret.str(); } */ string OCamlCodeGen::make_access(char const* name, GenInlineList* x, bool prefix = true) { ostringstream ret; if ( x == 0 ) { if (prefix && accessExpr != 0) { INLINE_LIST( ret, accessExpr, 0, false); ret << name; } else ret << name << ".contents"; // ref cell } else { ret << "("; INLINE_LIST( ret, x, 0, false ); ret << ")"; } return ret.str(); } string OCamlCodeGen::P() { return make_access("p", pExpr, false); } string OCamlCodeGen::PE() { return make_access("pe", peExpr, false); } string OCamlCodeGen::vEOF() { return make_access("eof", eofExpr, false); } string OCamlCodeGen::vCS() { return make_access("cs", csExpr); } string OCamlCodeGen::TOP() { return make_access("top", topExpr); } string OCamlCodeGen::STACK() { return make_access("stack", stackExpr); } string OCamlCodeGen::ACT() { return make_access("act", actExpr); } string OCamlCodeGen::TOKSTART() { return make_access("ts", tokstartExpr); } string OCamlCodeGen::TOKEND() { return make_access("te", tokendExpr); } string OCamlCodeGen::GET_WIDE_KEY() { if ( redFsm->anyConditions() ) return "_widec"; else { ostringstream ret; ret << "Char.code " << GET_KEY(); return ret.str(); } } string OCamlCodeGen::GET_WIDE_KEY( RedStateAp *state ) { if ( state->stateCondList.length() > 0 ) return "_widec"; else { ostringstream ret; ret << "Char.code " << GET_KEY(); return ret.str(); } } /* Write out level number of tabs. Makes the nested binary search nice * looking. */ string OCamlCodeGen::TABS( int level ) { string result; while ( level-- > 0 ) result += "\t"; return result; } /* Write out a key from the fsm code gen. Depends on wether or not the key is * signed. */ string OCamlCodeGen::KEY( Key key ) { ostringstream ret; if ( keyOps->isSigned || !hostLang->explicitUnsigned ) ret << key.getVal(); else ret << (unsigned long) key.getVal() << 'u'; return ret.str(); } string OCamlCodeGen::ALPHA_KEY( Key key ) { ostringstream ret; ret << key.getVal(); /* if (key.getVal() > 0xFFFF) { ret << key.getVal(); } else { ret << "'\\u" << std::hex << std::setw(4) << std::setfill('0') << key.getVal() << "'"; } */ //ret << "(char) " << key.getVal(); return ret.str(); } void OCamlCodeGen::EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { // The parser gives fexec two children. ret << "begin " << P() << " <- "; INLINE_LIST( ret, item->children, targState, inFinish ); ret << " - 1 end; "; } void OCamlCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { bool catch_all = false; ret << " begin match " << ACT() << " with\n"; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) { catch_all = true; ret << " | _ ->\n"; } else ret << " | " << lma->lmId << " ->\n"; /* Write the block and close it off. */ ret << " begin "; INLINE_LIST( ret, lma->children, targState, inFinish ); ret << " end\n"; } if (!catch_all) ret << " | _ -> assert false\n"; ret << " end;\n" "\t"; } void OCamlCodeGen::SET_ACT( ostream &ret, GenInlineItem *item ) { ret << ACT() << " <- " << item->lmId << "; "; } void OCamlCodeGen::SET_TOKEND( ostream &ret, GenInlineItem *item ) { /* The tokend action sets tokend. */ ret << TOKEND() << " <- " << P(); if ( item->offset != 0 ) out << "+" << item->offset; out << "; "; } void OCamlCodeGen::GET_TOKEND( ostream &ret, GenInlineItem *item ) { ret << TOKEND(); } void OCamlCodeGen::INIT_TOKSTART( ostream &ret, GenInlineItem *item ) { ret << TOKSTART() << " <- " << NULL_ITEM() << "; "; } void OCamlCodeGen::INIT_ACT( ostream &ret, GenInlineItem *item ) { ret << ACT() << " <- 0;"; } void OCamlCodeGen::SET_TOKSTART( ostream &ret, GenInlineItem *item ) { ret << TOKSTART() << " <- " << P() << "; "; } void OCamlCodeGen::SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish ) { if ( item->children->length() > 0 ) { /* Write the block and close it off. */ ret << "begin "; INLINE_LIST( ret, item->children, targState, inFinish ); ret << " end"; } } /* Write out an inline tree structure. Walks the list and possibly calls out * to virtual functions than handle language specific items in the tree. */ void OCamlCodeGen::INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Text: ret << item->data; break; case GenInlineItem::Goto: GOTO( ret, item->targState->id, inFinish ); break; case GenInlineItem::Call: CALL( ret, item->targState->id, targState, inFinish ); break; case GenInlineItem::Next: NEXT( ret, item->targState->id, inFinish ); break; case GenInlineItem::Ret: RET( ret, inFinish ); break; case GenInlineItem::PChar: ret << P(); break; case GenInlineItem::Char: ret << GET_KEY(); break; case GenInlineItem::Hold: ret << P() << " <- " << P() << " - 1; "; break; case GenInlineItem::Exec: EXEC( ret, item, targState, inFinish ); break; case GenInlineItem::Curs: CURS( ret, inFinish ); break; case GenInlineItem::Targs: TARGS( ret, inFinish, targState ); break; case GenInlineItem::Entry: ret << item->targState->id; break; case GenInlineItem::GotoExpr: GOTO_EXPR( ret, item, inFinish ); break; case GenInlineItem::CallExpr: CALL_EXPR( ret, item, targState, inFinish ); break; case GenInlineItem::NextExpr: NEXT_EXPR( ret, item, inFinish ); break; case GenInlineItem::LmSwitch: LM_SWITCH( ret, item, targState, inFinish ); break; case GenInlineItem::LmSetActId: SET_ACT( ret, item ); break; case GenInlineItem::LmSetTokEnd: SET_TOKEND( ret, item ); break; case GenInlineItem::LmGetTokEnd: GET_TOKEND( ret, item ); break; case GenInlineItem::LmInitTokStart: INIT_TOKSTART( ret, item ); break; case GenInlineItem::LmInitAct: INIT_ACT( ret, item ); break; case GenInlineItem::LmSetTokStart: SET_TOKSTART( ret, item ); break; case GenInlineItem::SubAction: SUB_ACTION( ret, item, targState, inFinish ); break; case GenInlineItem::Break: BREAK( ret, targState ); break; } } } /* Write out paths in line directives. Escapes any special characters. */ string OCamlCodeGen::LDIR_PATH( char *path ) { ostringstream ret; for ( char *pc = path; *pc != 0; pc++ ) { if ( *pc == '\\' ) ret << "\\\\"; else ret << *pc; } return ret.str(); } void OCamlCodeGen::ACTION( ostream &ret, GenAction *action, int targState, bool inFinish ) { /* Write the preprocessor line info for going into the source file. */ ocamlLineDirective( ret, action->loc.fileName, action->loc.line ); /* Write the block and close it off. */ ret << "\t\tbegin "; INLINE_LIST( ret, action->inlineList, targState, inFinish ); ret << " end;\n"; } void OCamlCodeGen::CONDITION( ostream &ret, GenAction *condition ) { ret << "\n"; ocamlLineDirective( ret, condition->loc.fileName, condition->loc.line ); INLINE_LIST( ret, condition->inlineList, 0, false ); } string OCamlCodeGen::ERROR_STATE() { ostringstream ret; if ( redFsm->errState != 0 ) ret << redFsm->errState->id; else ret << "-1"; return ret.str(); } string OCamlCodeGen::FIRST_FINAL_STATE() { ostringstream ret; if ( redFsm->firstFinState != 0 ) ret << redFsm->firstFinState->id; else ret << redFsm->nextStateId; return ret.str(); } void OCamlCodeGen::writeInit() { out << " begin\n"; if ( !noCS ) out << "\t" << vCS() << " <- " << START() << ";\n"; /* If there are any calls, then the stack top needs initialization. */ if ( redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "\t" << TOP() << " <- 0;\n"; if ( hasLongestMatch ) { out << " " << TOKSTART() << " <- " << NULL_ITEM() << ";\n" " " << TOKEND() << " <- " << NULL_ITEM() << ";\n" " " << ACT() << " <- 0;\n"; } out << " end;\n"; } string OCamlCodeGen::PRE_INCR(string val) { ostringstream ret; ret << "(" << val << " <- " << val << " + 1; " << val << ")"; return ret.str(); } string OCamlCodeGen::POST_INCR(string val) { ostringstream ret; ret << "(let temp = " << val << " in " << val << " <- " << val << " + 1; temp)"; return ret.str(); } string OCamlCodeGen::PRE_DECR(string val) { ostringstream ret; ret << "(" << val << " <- " << val << " - 1; " << val << ")"; return ret.str(); } string OCamlCodeGen::POST_DECR(string val) { ostringstream ret; ret << "(let temp = " << val << " in " << val << " <- " << val << " - 1; temp)"; return ret.str(); } string OCamlCodeGen::DATA_PREFIX() { if ( data_prefix.empty() ) // init { data_prefix = string(fsmName) + "_"; if (data_prefix.size() > 0) data_prefix[0] = ::tolower(data_prefix[0]); // uncapitalize } if ( !noPrefix ) return data_prefix; return ""; } /* Emit the alphabet data type. */ string OCamlCodeGen::ALPH_TYPE() { string ret = keyOps->alphType->data1; if ( keyOps->alphType->data2 != 0 ) { ret += " "; ret += + keyOps->alphType->data2; } return ret; } /* Emit the alphabet data type. */ string OCamlCodeGen::WIDE_ALPH_TYPE() { string ret; if ( redFsm->maxKey <= keyOps->maxKey ) ret = ALPH_TYPE(); else { long long maxKeyVal = redFsm->maxKey.getLongLong(); HostType *wideType = keyOps->typeSubsumes( keyOps->isSigned, maxKeyVal ); assert( wideType != 0 ); ret = wideType->data1; if ( wideType->data2 != 0 ) { ret += " "; ret += wideType->data2; } } return ret; } void OCamlCodeGen::STATE_IDS() { if ( redFsm->startState != 0 ) STATIC_VAR( "int", START() ) << " = " << START_STATE_ID() << TOP_SEP (); if ( !noFinal ) STATIC_VAR( "int" , FIRST_FINAL() ) << " = " << FIRST_FINAL_STATE() << TOP_SEP(); if ( !noError ) STATIC_VAR( "int", ERROR() ) << " = " << ERROR_STATE() << TOP_SEP(); out << "\n"; if ( !noEntry && entryPointNames.length() > 0 ) { for ( EntryNameVect::Iter en = entryPointNames; en.lte(); en++ ) { STATIC_VAR( "int", DATA_PREFIX() + "en_" + *en ) << " = " << entryPointIds[en.pos()] << TOP_SEP(); } out << "\n"; } } void OCamlCodeGen::writeStart() { out << START_STATE_ID(); } void OCamlCodeGen::writeFirstFinal() { out << FIRST_FINAL_STATE(); } void OCamlCodeGen::writeError() { out << ERROR_STATE(); } string OCamlCodeGen::GET_KEY() { ostringstream ret; if ( getKeyExpr != 0 ) { /* Emit the user supplied method of retrieving the key. */ ret << "("; INLINE_LIST( ret, getKeyExpr, 0, false ); ret << ")"; } else { /* Expression for retrieving the key, use simple dereference. */ ret << "data.[" << P() << "]"; } return ret.str(); } string OCamlCodeGen::NULL_ITEM() { return "-1"; } string OCamlCodeGen::POINTER() { // XXX C# has no pointers // multiple items seperated by commas can also be pointer types. return " "; } string OCamlCodeGen::PTR_CONST() { return ""; } std::ostream &OCamlCodeGen::OPEN_ARRAY( string type, string name ) { out << "let " << name << " : " << type << " array = [|" << endl; return out; } std::ostream &OCamlCodeGen::CLOSE_ARRAY() { return out << "|]" << TOP_SEP(); } string OCamlCodeGen::TOP_SEP() { return "\n"; // original syntax } string OCamlCodeGen::ARR_SEP() { return "; "; } string OCamlCodeGen::AT(const string& array, const string& index) { ostringstream ret; ret << array << ".(" << index << ")"; return ret.str(); } std::ostream &OCamlCodeGen::STATIC_VAR( string type, string name ) { out << "let " << name << " : " << type; return out; } string OCamlCodeGen::ARR_OFF( string ptr, string offset ) { // XXX C# can't do pointer arithmetic return "&" + ptr + "[" + offset + "]"; } string OCamlCodeGen::CAST( string type ) { return ""; // return "(" + type + ")"; } string OCamlCodeGen::UINT( ) { return "uint"; } std::ostream &OCamlCodeGen::SWITCH_DEFAULT() { out << " | _ -> ()\n"; return out; } string OCamlCodeGen::CTRL_FLOW() { return "if true then "; } void OCamlCodeGen::finishRagelDef() { if ( codeStyle == GenGoto || codeStyle == GenFGoto || codeStyle == GenIpGoto || codeStyle == GenSplit ) { /* For directly executable machines there is no required state * ordering. Choose a depth-first ordering to increase the * potential for fall-throughs. */ redFsm->depthFirstOrdering(); } else { /* The frontend will do this for us, but it may be a good idea to * force it if the intermediate file is edited. */ redFsm->sortByStateId(); } /* Choose default transitions and the single transition. */ redFsm->chooseDefaultSpan(); /* Maybe do flat expand, otherwise choose single. */ if ( codeStyle == GenFlat || codeStyle == GenFFlat ) redFsm->makeFlat(); else redFsm->chooseSingle(); /* If any errors have occured in the input file then don't write anything. */ if ( gblErrorCount > 0 ) return; if ( codeStyle == GenSplit ) redFsm->partitionFsm( numSplitPartitions ); if ( codeStyle == GenIpGoto || codeStyle == GenSplit ) redFsm->setInTrans(); /* Anlayze Machine will find the final action reference counts, among * other things. We will use these in reporting the usage * of fsm directives in action code. */ analyzeMachine(); /* Determine if we should use indicies. */ calcIndexSize(); } ostream &OCamlCodeGen::source_warning( const InputLoc &loc ) { cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: "; return cerr; } ostream &OCamlCodeGen::source_error( const InputLoc &loc ) { gblErrorCount += 1; assert( sourceFileName != 0 ); cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": "; return cerr; } ragel-6.10/ragel/csgoto.h0000664000175000017500000000577613065111230012225 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOTOCODEGEN_H #define _GOTOCODEGEN_H #include #include "cscodegen.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; struct GenStateCond; /* * Goto driven fsm. */ class CSharpGotoCodeGen : virtual public CSharpFsmCodeGen, public CSharpCodeGen { public: CSharpGotoCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpCodeGen(out) {} std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &STATE_GOTOS(); std::ostream &TRANSITIONS(); std::ostream &EXEC_FUNCS(); std::ostream &FINISH_CASES(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState ); virtual unsigned int TO_STATE_ACTION( RedStateAp *state ); virtual unsigned int FROM_STATE_ACTION( RedStateAp *state ); virtual unsigned int EOF_ACTION( RedStateAp *state ); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); void COND_TRANSLATE( GenStateCond *stateCond, int level ); void emitCondBSearch( RedStateAp *state, int level, int low, int high ); void STATE_CONDS( RedStateAp *state, bool genDefault ); virtual std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); void emitSingleSwitch( RedStateAp *state ); void emitRangeBSearch( RedStateAp *state, int level, int low, int high ); /* Called from STATE_GOTOS just before writing the gotos */ virtual void GOTO_HEADER( RedStateAp *state ); virtual void STATE_GOTO_ERROR(); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/rubyflat.cpp0000664000175000017500000005071713065111230013105 00000000000000/* * Copyright 2001-2007 Adrian Thurston * Copyright 2007 Victor Hugo Borja */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rubyflat.h" #include "ragel.h" #include "redfsm.h" #include "gendata.h" using std::ostream; using std::string; std::ostream &RubyFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyFlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyFlatCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, true ); } } genLineDirective( out ); return out; } std::ostream &RubyFlatCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyFlatCodeGen::KEYS() { START_ARRAY_LINE(); int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just low key and high key. */ ARRAY_ITEM( KEY( st->lowKey ), ++totalTrans, false ); ARRAY_ITEM( KEY( st->highKey ), ++totalTrans, false ); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT( 0 ), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::INDICIES() { int totalTrans = 0; START_ARRAY_LINE(); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->transList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->lowKey, st->highKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { ARRAY_ITEM( KEY( st->transList[pos]->id ), ++totalTrans, false ); } } /* The state's default index goes next. */ if ( st->defTrans != 0 ) ARRAY_ITEM( KEY( st->defTrans->id ), ++totalTrans, false ); } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT( 0 ), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::FLAT_INDEX_OFFSET() { START_ARRAY_LINE(); int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ ARRAY_ITEM( INT( curIndOffset ), ++totalStateNum, st.last() ); /* Move the index offset ahead. */ if ( st->transList != 0 ) curIndOffset += keyOps->span( st->lowKey, st->highKey ); if ( st->defTrans != 0 ) curIndOffset += 1; } END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::KEY_SPANS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->transList != 0 ) span = keyOps->span( st->lowKey, st->highKey ); ARRAY_ITEM( INT( span ), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::TO_STATE_ACTIONS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ ARRAY_ITEM( INT( TO_STATE_ACTION(st) ), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::FROM_STATE_ACTIONS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ ARRAY_ITEM( INT( FROM_STATE_ACTION(st) ), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::EOF_ACTIONS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ ARRAY_ITEM( INT( EOF_ACTION(st) ), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::EOF_TRANS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } /* Write any eof action. */ ARRAY_ITEM( INT(trans), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::TRANS_TARGS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ START_ARRAY_LINE(); int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ ARRAY_ITEM( INT( trans->targ->id ), ++totalStates, t >= redFsm->transSet.length()-1 ); } END_ARRAY_LINE(); delete[] transPtrs; return out; } std::ostream &RubyFlatCodeGen::TRANS_ACTIONS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ START_ARRAY_LINE(); int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; ARRAY_ITEM( INT( TRANS_ACTION( trans ) ), ++totalAct, t >= redFsm->transSet.length()-1 ); } END_ARRAY_LINE(); delete[] transPtrs; return out; } void RubyFlatCodeGen::LOCATE_TRANS() { out << " _keys = " << vCS() << " << 1\n" " _inds = " << IO() << "[" << vCS() << "]\n" " _slen = " << SP() << "[" << vCS() << "]\n" " _wide = " << GET_WIDE_KEY() << "\n" " _trans = if ( _slen > 0 && \n" " " << K() << "[_keys] <= _wide && \n" " " << "_wide <= " << K() << "[_keys + 1] \n" " ) then\n" " " << I() << "[ _inds + _wide - " << K() << "[_keys] ] \n" " else \n" " " << I() << "[ _inds + _slen ]\n" " end\n" ""; } std::ostream &RubyFlatCodeGen::COND_INDEX_OFFSET() { START_ARRAY_LINE(); int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ ARRAY_ITEM( INT( curIndOffset ), ++totalStateNum, st.last() ); /* Move the index offset ahead. */ if ( st->condList != 0 ) curIndOffset += keyOps->span( st->condLowKey, st->condHighKey ); } END_ARRAY_LINE(); return out; } void RubyFlatCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << "\n" " _keys = " << vCS() << " << 1\n" " _conds = " << CO() << "[" << vCS() << "]\n" " _slen = " << CSP() << "[" << vCS() << "]\n" " _wide = " << GET_WIDE_KEY() << "\n" " _cond = if ( _slen > 0 && \n" " " << CK() << "[_keys] <= _wide &&\n" " " << "_wide <= " << CK() << "[_keys + 1]\n" " ) then \n" " " << C() << "[ _conds + _wide - " << CK() << "[_keys]" << " ]\n" " else\n" " 0\n" " end\n"; out << " case _cond \n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " when " << condSpace->condSpaceId + 1 << " then\n"; out << TABS(2) << "_widec = " << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "))\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) then \n" << TABS(3) << " _widec += " << condValOffset << "\n" "end\n"; } } out << " end # _cond switch \n"; } std::ostream &RubyFlatCodeGen::CONDS() { int totalTrans = 0; START_ARRAY_LINE(); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->condList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->condList[pos] != 0 ) ARRAY_ITEM( INT( st->condList[pos]->condSpaceId + 1 ), ++totalTrans, false ); else ARRAY_ITEM( INT( 0 ), ++totalTrans, false ); } } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT( 0 ), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::COND_KEYS() { START_ARRAY_LINE(); int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just cond low key and cond high key. */ ARRAY_ITEM( KEY( st->condLowKey ), ++totalTrans, false ); ARRAY_ITEM( KEY( st->condHighKey ), ++totalTrans, false ); } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT( 0 ), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyFlatCodeGen::COND_KEY_SPANS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->condList != 0 ) span = keyOps->span( st->condLowKey, st->condHighKey ); ARRAY_ITEM( INT( span ), ++totalStateNum, false ); } END_ARRAY_LINE(); return out; } void RubyFlatCodeGen::GOTO( ostream &out, int gotoDest, bool inFinish ) { out << " begin\n" " " << vCS() << " = " << gotoDest << "\n" " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; } void RubyFlatCodeGen::CALL( ostream &out, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << "+= 1\n" " " << vCS() << " = " << callDest << "\n" " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyFlatCodeGen::CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << " += 1\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, targState, inFinish ); out << ")\n"; out << " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyFlatCodeGen::RET( ostream &out, bool inFinish ) { out << " begin\n" " " << TOP() << " -= 1\n" " " << vCS() << " = " << STACK() << "[" << TOP() << "]\n"; if ( postPopExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, postPopExpr, 0, false ); out << "end\n"; } out << " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; } void RubyFlatCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void RubyFlatCodeGen::GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ) { out << " begin\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, 0, inFinish ); out << ")\n"; out << " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; } void RubyFlatCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void RubyFlatCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void RubyFlatCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void RubyFlatCodeGen::BREAK( ostream &out, int targState ) { out << " begin\n" " " << P() << " += 1\n" " _trigger_goto = true\n" " _goto_level = _out\n" " break\n" " end\n"; } int RubyFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; return act; } int RubyFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; return act; } int RubyFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; return act; } int RubyFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; return act; } void RubyFlatCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void RubyFlatCodeGen::writeExec() { out << "begin # ragel flat\n" " testEof = false\n" " _slen, _trans, _keys, _inds"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; if ( redFsm->anyConditions() ) out << ", _cond, _conds, _widec"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) out << ", _acts, _nacts"; out << " = nil\n"; out << " _goto_level = 0\n" " _resume = 10\n" " _eof_trans = 15\n" " _again = 20\n" " _test_eof = 30\n" " _out = 40\n"; out << " while true\n" " _trigger_goto = false\n" " if _goto_level <= 0\n"; if ( !noEnd ) { out << " if " << P() << " == " << PE() << "\n" " _goto_level = _test_eof\n" " next\n" " end\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } /* The resume label. */ out << " end\n" " if _goto_level <= _resume\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << FSA() << "[" << vCS() << "]\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while _nacts > 0\n" " _nacts -= 1\n" " _acts += 1\n" " case " << A() << "[_acts - 1]\n"; FROM_STATE_ACTION_SWITCH(); out << " end # from state action switch\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) { out << " end\n" " if _goto_level <= _eof_trans\n"; } if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << "\n"; out << " " << vCS() << " = " << TT() << "[_trans]\n"; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] != 0\n" " _acts = " << TA() << "[_trans]\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while _nacts > 0\n" " _nacts -= 1\n" " _acts += 1\n" " case " << A() << "[_acts - 1]\n"; ACTION_SWITCH(); out << " end # action switch\n" " end\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } /* The again label. */ out << " end\n" " if _goto_level <= _again\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << TSA() << "[" << vCS() << "]\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while _nacts > 0\n" " _nacts -= 1\n" " _acts += 1\n" " case " << A() << "[_acts - 1]\n"; TO_STATE_ACTION_SWITCH() << " end # to state action switch\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } out << " " << P() << " += 1\n"; if ( !noEnd ) { out << " if " << P() << " != " << PE() << "\n" " _goto_level = _resume\n" " next\n" " end\n"; } else { out << " _goto_level = _resume\n" " next\n"; } /* The test_eof label. */ out << " end\n" " if _goto_level <= _test_eof\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << "\n"; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " _goto_level = _eof_trans\n" " next;\n" " end\n"; } if ( redFsm->anyEofActions() ) { out << " begin\n" " __acts = " << EA() << "[" << vCS() << "]\n" " __nacts = " << A() << "[__acts]\n" << " __acts += 1\n" " while ( __nacts > 0 ) \n" " __nacts -= 1\n" " __acts += 1\n" " case ( "<< A() << "[__acts-1] ) \n"; EOF_ACTION_SWITCH() << " end\n" " end\n" " if _trigger_goto\n" " next\n" " end\n" " end\n"; } out << " end\n"; } out << " end\n" " if _goto_level <= _out\n" " break\n" " end\n"; /* The loop for faking goto. */ out << " end\n"; /* Wrapping the execute block. */ out << " end\n"; } /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/common.cpp0000664000175000017500000003077413065111230012546 00000000000000/* * Copyright 2006-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "pcheck.h" #include "common.h" #include "stdlib.h" #include #include HostType hostTypesC[] = { { "char", 0, "char", true, true, false, CHAR_MIN, CHAR_MAX, 0, 0, sizeof(char) }, { "unsigned", "char", "uchar", false, true, false, 0, 0, 0, UCHAR_MAX, sizeof(unsigned char) }, { "short", 0, "short", true, true, false, SHRT_MIN, SHRT_MAX, 0, 0, sizeof(short) }, { "unsigned", "short", "ushort", false, true, false, 0, 0, 0, USHRT_MAX, sizeof(unsigned short) }, { "int", 0, "int", true, true, false, INT_MIN, INT_MAX, 0, 0, sizeof(int) }, { "unsigned", "int", "uint", false, true, false, 0, 0, 0, UINT_MAX, sizeof(unsigned int) }, { "long", 0, "long", true, true, false, LONG_MIN, LONG_MAX, 0, 0, sizeof(long) }, { "unsigned", "long", "ulong", false, true, false, 0, 0, 0, ULONG_MAX, sizeof(unsigned long) } }; #define S8BIT_MIN -128 #define S8BIT_MAX 127 #define U8BIT_MIN 0 #define U8BIT_MAX 255 #define S16BIT_MIN -32768 #define S16BIT_MAX 32767 #define U16BIT_MIN 0 #define U16BIT_MAX 65535 #define S31BIT_MIN -1073741824L #define S31BIT_MAX 1073741823L #define S32BIT_MIN -2147483648L #define S32BIT_MAX 2147483647L #define U32BIT_MIN 0 #define U32BIT_MAX 4294967295UL #define S64BIT_MIN -9223372036854775807LL #define S64BIT_MAX 9223372036854775807LL #define U64BIT_MIN 0 #define U64BIT_MAX 18446744073709551615ULL HostType hostTypesD[] = { { "byte", 0, "byte", true, true, false, CHAR_MIN, CHAR_MAX, 0, 0, 1 }, { "ubyte", 0, "ubyte", false, true, false, 0, 0, 0, UCHAR_MAX, 1 }, { "char", 0, "char", false, true, false, 0, 0, 0, UCHAR_MAX, 1 }, { "short", 0, "short", true, true, false, SHRT_MIN, SHRT_MAX, 0, 0, 2 }, { "ushort", 0, "ushort", false, true, false, 0, 0, 0, USHRT_MAX, 2 }, { "wchar", 0, "wchar", false, true, false, 0, 0, 0, USHRT_MAX, 2 }, { "int", 0, "int", true, true, false, INT_MIN, INT_MAX, 0, 0, 4 }, { "uint", 0, "uint", false, true, false, 0, 0, 0, UINT_MAX, 4 }, { "dchar", 0, "dchar", false, true, false, 0, 0, 0, UINT_MAX, 4 } }; HostType hostTypesGo[] = { { "byte", 0, "uint8", false, true, false, 0, 0, U8BIT_MIN, U8BIT_MAX, 1 }, { "int8", 0, "int8", true, true, false, S8BIT_MIN, S8BIT_MAX, 0, 0, 1 }, { "uint8", 0, "uint8", false, true, false, 0, 0, U8BIT_MIN, U8BIT_MAX, 1 }, { "int16", 0, "int16", true, true, false, S16BIT_MIN, S16BIT_MAX, 0, 0, 2 }, { "uint16", 0, "uint16", false, true, false, 0, 0, U16BIT_MIN, U16BIT_MAX, 2 }, { "int32", 0, "int32", true, true, false, S32BIT_MIN, S32BIT_MAX, 0, 0, 4 }, { "uint32", 0, "uint32", false, true, false, 0, 0, U32BIT_MIN, U32BIT_MAX, 4 }, { "int64", 0, "int64", true, true, false, S64BIT_MIN, S64BIT_MAX, 0, 0, 8 }, { "uint64", 0, "uint64", false, true, false, 0, 0, U64BIT_MIN, U64BIT_MAX, 8 }, { "rune", 0, "int32", true, true, true, S32BIT_MIN, S32BIT_MAX, 0, 0, 4 } }; HostType hostTypesJava[] = { { "byte", 0, "byte", true, true, false, CHAR_MIN, CHAR_MAX, 0, 0, 1 }, { "short", 0, "short", true, true, false, SHRT_MIN, SHRT_MAX, 0, 0, 2 }, { "char", 0, "char", false, true, false, 0, 0, 0, USHRT_MAX, 2 }, { "int", 0, "int", true, true, false, INT_MIN, INT_MAX, 0, 0, 4 }, }; /* What are the appropriate types for ruby? */ HostType hostTypesRuby[] = { { "char", 0, "char", true, true, false, CHAR_MIN, CHAR_MAX, 0, 0, 1 }, { "int", 0, "int", true, true, false, INT_MIN, INT_MAX, 0, 0, 4 }, }; HostType hostTypesCSharp[] = { { "sbyte", 0, "sbyte", true, true, false, CHAR_MIN, CHAR_MAX, 0, 0, 1 }, { "byte", 0, "byte", false, true, false, 0, 0, 0, UCHAR_MAX, 1 }, { "short", 0, "short", true, true, false, SHRT_MIN, SHRT_MAX, 0, 0, 2 }, { "ushort", 0, "ushort", false, true, false, 0, 0, 0, USHRT_MAX, 2 }, { "char", 0, "char", false, true, true, 0, 0, 0, USHRT_MAX, 2 }, { "int", 0, "int", true, true, false, INT_MIN, INT_MAX, 0, 0, 4 }, { "uint", 0, "uint", false, true, false, 0, 0, 0, UINT_MAX, 4 }, { "long", 0, "long", true, true, false, LONG_MIN, LONG_MAX, 0, 0, 8 }, { "ulong", 0, "ulong", false, true, false, 0, 0, 0, ULONG_MAX, 8 } }; HostType hostTypesOCaml[] = { { "int", 0, "int", true, true, false, S31BIT_MIN, S31BIT_MAX, 0, 0, 4 }, }; HostLang hostLangC = { HostLang::C, hostTypesC, 8, hostTypesC+0, true }; HostLang hostLangD = { HostLang::D, hostTypesD, 9, hostTypesD+2, true }; HostLang hostLangD2 = { HostLang::D2, hostTypesD, 9, hostTypesD+2, true }; HostLang hostLangGo = { HostLang::Go, hostTypesGo, 10, hostTypesGo+0, false }; HostLang hostLangJava = { HostLang::Java, hostTypesJava, 4, hostTypesJava+2, false }; HostLang hostLangRuby = { HostLang::Ruby, hostTypesRuby, 2, hostTypesRuby+0, false }; HostLang hostLangCSharp = { HostLang::CSharp, hostTypesCSharp, 9, hostTypesCSharp+4, true }; HostLang hostLangOCaml = { HostLang::OCaml, hostTypesOCaml, 1, hostTypesOCaml+0, false }; HostLang *hostLang = &hostLangC; HostType *findAlphType( const char *s1 ) { for ( int i = 0; i < hostLang->numHostTypes; i++ ) { if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 && hostLang->hostTypes[i].data2 == 0 ) { return hostLang->hostTypes + i; } } return 0; } HostType *findAlphType( const char *s1, const char *s2 ) { for ( int i = 0; i < hostLang->numHostTypes; i++ ) { if ( strcmp( s1, hostLang->hostTypes[i].data1 ) == 0 && hostLang->hostTypes[i].data2 != 0 && strcmp( s2, hostLang->hostTypes[i].data2 ) == 0 ) { return hostLang->hostTypes + i; } } return 0; } HostType *findAlphTypeInternal( const char *s1 ) { for ( int i = 0; i < hostLang->numHostTypes; i++ ) { if ( strcmp( s1, hostLang->hostTypes[i].internalName ) == 0 ) return hostLang->hostTypes + i; } return 0; } /* Construct a new parameter checker with for paramSpec. */ ParamCheck::ParamCheck( const char *paramSpec, int argc, const char **argv ) : state(noparam), argOffset(0), curArg(0), iCurArg(1), paramSpec(paramSpec), argc(argc), argv(argv) { } /* Check a single option. Returns the index of the next parameter. Sets p to * the arg character if valid, 0 otherwise. Sets parg to the parameter arg if * there is one, NULL otherwise. */ bool ParamCheck::check() { bool requiresParam; if ( iCurArg >= argc ) { /* Off the end of the arg list. */ state = noparam; return false; } if ( argOffset != 0 && *argOffset == 0 ) { /* We are at the end of an arg string. */ iCurArg += 1; if ( iCurArg >= argc ) { state = noparam; return false; } argOffset = 0; } if ( argOffset == 0 ) { /* Set the current arg. */ curArg = argv[iCurArg]; /* We are at the beginning of an arg string. */ if ( argv[iCurArg] == 0 || /* Argv[iCurArg] is null. */ argv[iCurArg][0] != '-' || /* Not a param. */ argv[iCurArg][1] == 0 ) { /* Only a dash. */ parameter = 0; paramArg = 0; iCurArg += 1; state = noparam; return true; } argOffset = argv[iCurArg] + 1; } /* Get the arg char. */ char argChar = *argOffset; /* Loop over all the parms and look for a match. */ const char *pSpec = paramSpec; while ( *pSpec != 0 ) { char pSpecChar = *pSpec; /* If there is a ':' following the char then * it requires a parm. If a parm is required * then move ahead two in the parmspec. Otherwise * move ahead one in the parm spec. */ if ( pSpec[1] == ':' ) { requiresParam = true; pSpec += 2; } else { requiresParam = false; pSpec += 1; } /* Do we have a match. */ if ( argChar == pSpecChar ) { if ( requiresParam ) { if ( argOffset[1] == 0 ) { /* The param must follow. */ if ( iCurArg + 1 == argc ) { /* We are the last arg so there * cannot be a parameter to it. */ parameter = argChar; paramArg = 0; iCurArg += 1; argOffset = 0; state = invalid; return true; } else { /* the parameter to the arg is the next arg. */ parameter = pSpecChar; paramArg = argv[iCurArg + 1]; iCurArg += 2; argOffset = 0; state = match; return true; } } else { /* The param for the arg is built in. */ parameter = pSpecChar; paramArg = argOffset + 1; iCurArg += 1; argOffset = 0; state = match; return true; } } else { /* Good, we matched the parm and no * arg is required. */ parameter = pSpecChar; paramArg = 0; argOffset += 1; state = match; return true; } } } /* We did not find a match. Bad Argument. */ parameter = argChar; paramArg = 0; argOffset += 1; state = invalid; return true; } /* Counts newlines before sending sync. */ int output_filter::sync( ) { line += 1; return std::filebuf::sync(); } /* Counts newlines before sending data out to file. */ std::streamsize output_filter::xsputn( const char *s, std::streamsize n ) { for ( int i = 0; i < n; i++ ) { if ( s[i] == '\n' ) line += 1; } return std::filebuf::xsputn( s, n ); } /* Scans a string looking for the file extension. If there is a file * extension then pointer returned points to inside the string * passed in. Otherwise returns null. */ const char *findFileExtension( const char *stemFile ) { const char *ppos = stemFile + strlen(stemFile) - 1; /* Scan backwards from the end looking for the first dot. * If we encounter a '/' before the first dot, then stop the scan. */ while ( 1 ) { /* If we found a dot or got to the beginning of the string then * we are done. */ if ( ppos == stemFile || *ppos == '.' ) break; /* If we hit a / then there is no extension. Done. */ if ( *ppos == '/' ) { ppos = stemFile; break; } ppos--; } /* If we got to the front of the string then bail we * did not find an extension */ if ( ppos == stemFile ) ppos = 0; return ppos; } /* Make a file name from a stem. Removes the old filename suffix and * replaces it with a new one. Returns a newed up string. */ const char *fileNameFromStem( const char *stemFile, const char *suffix ) { long len = strlen( stemFile ); assert( len > 0 ); /* Get the extension. */ const char *ppos = findFileExtension( stemFile ); /* If an extension was found, then shorten what we think the len is. */ if ( ppos != 0 ) len = ppos - stemFile; /* Make the return string from the stem and the suffix. */ char *retVal = new char[ len + strlen( suffix ) + 1 ]; strncpy( retVal, stemFile, len ); strcpy( retVal + len, suffix ); return retVal; } exit_object endp; void operator<<( std::ostream &out, exit_object & ) { out << std::endl; exit(1); } ragel-6.10/ragel/fsmmin.cpp0000664000175000017500000005536113065111230012546 00000000000000/* * Copyright 2002 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "fsmgraph.h" #include "mergesort.h" int FsmAp::partitionRound( StateAp **statePtrs, MinPartition *parts, int numParts ) { /* Need a mergesort object and a single partition compare. */ MergeSort mergeSort; PartitionCompare partCompare; /* For each partition. */ for ( int p = 0; p < numParts; p++ ) { /* Fill the pointer array with the states in the partition. */ StateList::Iter state = parts[p].list; for ( int s = 0; state.lte(); state++, s++ ) statePtrs[s] = state; /* Sort the states using the partitioning compare. */ int numStates = parts[p].list.length(); mergeSort.sort( statePtrs, numStates ); /* Assign the states into partitions based on the results of the sort. */ int destPart = p, firstNewPart = numParts; for ( int s = 1; s < numStates; s++ ) { /* If this state differs from the last then move to the next partition. */ if ( partCompare.compare( statePtrs[s-1], statePtrs[s] ) < 0 ) { /* The new partition is the next avail spot. */ destPart = numParts; numParts += 1; } /* If the state is not staying in the first partition, then * transfer it to its destination partition. */ if ( destPart != p ) { StateAp *state = parts[p].list.detach( statePtrs[s] ); parts[destPart].list.append( state ); } } /* Fix the partition pointer for all the states that got moved to a new * partition. This must be done after the states are transfered so the * result of the sort is not altered. */ for ( int newPart = firstNewPart; newPart < numParts; newPart++ ) { StateList::Iter state = parts[newPart].list; for ( ; state.lte(); state++ ) state->alg.partition = &parts[newPart]; } } return numParts; } /** * \brief Minimize by partitioning version 1. * * Repeatedly tries to split partitions until all partitions are unsplittable. * Produces the most minimal FSM possible. */ void FsmAp::minimizePartition1() { /* Need one mergesort object and partition compares. */ MergeSort mergeSort; InitPartitionCompare initPartCompare; /* Nothing to do if there are no states. */ if ( stateList.length() == 0 ) return; /* * First thing is to partition the states by final state status and * transition functions. This gives us an initial partitioning to work * with. */ /* Make a array of pointers to states. */ int numStates = stateList.length(); StateAp** statePtrs = new StateAp*[numStates]; /* Fill up an array of pointers to the states for easy sorting. */ StateList::Iter state = stateList; for ( int s = 0; state.lte(); state++, s++ ) statePtrs[s] = state; /* Sort the states using the array of states. */ mergeSort.sort( statePtrs, numStates ); /* An array of lists of states is used to partition the states. */ MinPartition *parts = new MinPartition[numStates]; /* Assign the states into partitions. */ int destPart = 0; for ( int s = 0; s < numStates; s++ ) { /* If this state differs from the last then move to the next partition. */ if ( s > 0 && initPartCompare.compare( statePtrs[s-1], statePtrs[s] ) < 0 ) { /* Move to the next partition. */ destPart += 1; } /* Put the state into its partition. */ statePtrs[s]->alg.partition = &parts[destPart]; parts[destPart].list.append( statePtrs[s] ); } /* We just moved all the states from the main list into partitions without * taking them off the main list. So clean up the main list now. */ stateList.abandon(); /* Split partitions. */ int numParts = destPart + 1; while ( true ) { /* Test all partitions for splitting. */ int newNum = partitionRound( statePtrs, parts, numParts ); /* When no partitions can be split, stop. */ if ( newNum == numParts ) break; numParts = newNum; } /* Fuse states in the same partition. The states will end up back on the * main list. */ fusePartitions( parts, numParts ); /* Cleanup. */ delete[] statePtrs; delete[] parts; } /* Split partitions that need splittting, decide which partitions might need * to be split as a result, continue until there are no more that might need * to be split. */ int FsmAp::splitCandidates( StateAp **statePtrs, MinPartition *parts, int numParts ) { /* Need a mergesort and a partition compare. */ MergeSort mergeSort; PartitionCompare partCompare; /* The lists of unsplitable (partList) and splitable partitions. * Only partitions in the splitable list are check for needing splitting. */ PartitionList partList, splittable; /* Initially, all partitions are born from a split (the initial * partitioning) and can cause other partitions to be split. So any * partition with a state with a transition out to another partition is a * candidate for splitting. This will make every partition except possibly * partitions of final states split candidates. */ for ( int p = 0; p < numParts; p++ ) { /* Assume not active. */ parts[p].active = false; /* Look for a trans out of any state in the partition. */ for ( StateList::Iter state = parts[p].list; state.lte(); state++ ) { /* If there is at least one transition out to another state then * the partition becomes splittable. */ if ( state->outList.length() > 0 ) { parts[p].active = true; break; } } /* If it was found active then it goes on the splittable list. */ if ( parts[p].active ) splittable.append( &parts[p] ); else partList.append( &parts[p] ); } /* While there are partitions that are splittable, pull one off and try * to split it. If it splits, determine which partitions may now be split * as a result of the newly split partition. */ while ( splittable.length() > 0 ) { MinPartition *partition = splittable.detachFirst(); /* Fill the pointer array with the states in the partition. */ StateList::Iter state = partition->list; for ( int s = 0; state.lte(); state++, s++ ) statePtrs[s] = state; /* Sort the states using the partitioning compare. */ int numStates = partition->list.length(); mergeSort.sort( statePtrs, numStates ); /* Assign the states into partitions based on the results of the sort. */ MinPartition *destPart = partition; int firstNewPart = numParts; for ( int s = 1; s < numStates; s++ ) { /* If this state differs from the last then move to the next partition. */ if ( partCompare.compare( statePtrs[s-1], statePtrs[s] ) < 0 ) { /* The new partition is the next avail spot. */ destPart = &parts[numParts]; numParts += 1; } /* If the state is not staying in the first partition, then * transfer it to its destination partition. */ if ( destPart != partition ) { StateAp *state = partition->list.detach( statePtrs[s] ); destPart->list.append( state ); } } /* Fix the partition pointer for all the states that got moved to a new * partition. This must be done after the states are transfered so the * result of the sort is not altered. */ int newPart; for ( newPart = firstNewPart; newPart < numParts; newPart++ ) { StateList::Iter state = parts[newPart].list; for ( ; state.lte(); state++ ) state->alg.partition = &parts[newPart]; } /* Put the partition we just split and any new partitions that came out * of the split onto the inactive list. */ partition->active = false; partList.append( partition ); for ( newPart = firstNewPart; newPart < numParts; newPart++ ) { parts[newPart].active = false; partList.append( &parts[newPart] ); } if ( destPart == partition ) continue; /* Now determine which partitions are splittable as a result of * splitting partition by walking the in lists of the states in * partitions that got split. Partition is the faked first item in the * loop. */ MinPartition *causalPart = partition; newPart = firstNewPart - 1; while ( newPart < numParts ) { /* Loop all states in the causal partition. */ StateList::Iter state = causalPart->list; for ( ; state.lte(); state++ ) { /* Walk all transition into the state and put the partition * that the from state is in onto the splittable list. */ for ( TransInList::Iter trans = state->inList; trans.lte(); trans++ ) { MinPartition *fromPart = trans->fromState->alg.partition; if ( ! fromPart->active ) { fromPart->active = true; partList.detach( fromPart ); splittable.append( fromPart ); } } } newPart += 1; causalPart = &parts[newPart]; } } return numParts; } /** * \brief Minimize by partitioning version 2 (best alg). * * Repeatedly tries to split partitions that may splittable until there are no * more partitions that might possibly need splitting. Runs faster than * version 1. Produces the most minimal fsm possible. */ void FsmAp::minimizePartition2() { /* Need a mergesort and an initial partition compare. */ MergeSort mergeSort; InitPartitionCompare initPartCompare; /* Nothing to do if there are no states. */ if ( stateList.length() == 0 ) return; /* * First thing is to partition the states by final state status and * transition functions. This gives us an initial partitioning to work * with. */ /* Make a array of pointers to states. */ int numStates = stateList.length(); StateAp** statePtrs = new StateAp*[numStates]; /* Fill up an array of pointers to the states for easy sorting. */ StateList::Iter state = stateList; for ( int s = 0; state.lte(); state++, s++ ) statePtrs[s] = state; /* Sort the states using the array of states. */ mergeSort.sort( statePtrs, numStates ); /* An array of lists of states is used to partition the states. */ MinPartition *parts = new MinPartition[numStates]; /* Assign the states into partitions. */ int destPart = 0; for ( int s = 0; s < numStates; s++ ) { /* If this state differs from the last then move to the next partition. */ if ( s > 0 && initPartCompare.compare( statePtrs[s-1], statePtrs[s] ) < 0 ) { /* Move to the next partition. */ destPart += 1; } /* Put the state into its partition. */ statePtrs[s]->alg.partition = &parts[destPart]; parts[destPart].list.append( statePtrs[s] ); } /* We just moved all the states from the main list into partitions without * taking them off the main list. So clean up the main list now. */ stateList.abandon(); /* Split partitions. */ int numParts = splitCandidates( statePtrs, parts, destPart+1 ); /* Fuse states in the same partition. The states will end up back on the * main list. */ fusePartitions( parts, numParts ); /* Cleanup. */ delete[] statePtrs; delete[] parts; } void FsmAp::initialMarkRound( MarkIndex &markIndex ) { /* P and q for walking pairs. */ StateAp *p = stateList.head, *q; /* Need an initial partition compare. */ InitPartitionCompare initPartCompare; /* Walk all unordered pairs of (p, q) where p != q. * The second depth of the walk stops before reaching p. This * gives us all unordered pairs of states (p, q) where p != q. */ while ( p != 0 ) { q = stateList.head; while ( q != p ) { /* If the states differ on final state status, out transitions or * any transition data then they should be separated on the initial * round. */ if ( initPartCompare.compare( p, q ) != 0 ) markIndex.markPair( p->alg.stateNum, q->alg.stateNum ); q = q->next; } p = p->next; } } bool FsmAp::markRound( MarkIndex &markIndex ) { /* P an q for walking pairs. Take note if any pair gets marked. */ StateAp *p = stateList.head, *q; bool pairWasMarked = false; /* Need a mark comparison. */ MarkCompare markCompare; /* Walk all unordered pairs of (p, q) where p != q. * The second depth of the walk stops before reaching p. This * gives us all unordered pairs of states (p, q) where p != q. */ while ( p != 0 ) { q = stateList.head; while ( q != p ) { /* Should we mark the pair? */ if ( !markIndex.isPairMarked( p->alg.stateNum, q->alg.stateNum ) ) { if ( markCompare.shouldMark( markIndex, p, q ) ) { markIndex.markPair( p->alg.stateNum, q->alg.stateNum ); pairWasMarked = true; } } q = q->next; } p = p->next; } return pairWasMarked; } /** * \brief Minimize by pair marking. * * Decides if each pair of states is distinct or not. Uses O(n^2) memory and * should only be used on small graphs. Produces the most minmimal FSM * possible. */ void FsmAp::minimizeStable() { /* Set the state numbers. */ setStateNumbers( 0 ); /* This keeps track of which pairs have been marked. */ MarkIndex markIndex( stateList.length() ); /* Mark pairs where final stateness, out trans, or trans data differ. */ initialMarkRound( markIndex ); /* While the last round of marking succeeded in marking a state * continue to do another round. */ int modified = markRound( markIndex ); while (modified) modified = markRound( markIndex ); /* Merge pairs that are unmarked. */ fuseUnmarkedPairs( markIndex ); } bool FsmAp::minimizeRound() { /* Nothing to do if there are no states. */ if ( stateList.length() == 0 ) return false; /* Need a mergesort on approx compare and an approx compare. */ MergeSort mergeSort; ApproxCompare approxCompare; /* Fill up an array of pointers to the states. */ StateAp **statePtrs = new StateAp*[stateList.length()]; StateList::Iter state = stateList; for ( int s = 0; state.lte(); state++, s++ ) statePtrs[s] = state; bool modified = false; /* Sort The list. */ mergeSort.sort( statePtrs, stateList.length() ); /* Walk the list looking for duplicates next to each other, * merge in any duplicates. */ StateAp **pLast = statePtrs; StateAp **pState = statePtrs + 1; for ( int i = 1; i < stateList.length(); i++, pState++ ) { if ( approxCompare.compare( *pLast, *pState ) == 0 ) { /* Last and pState are the same, so fuse together. Move forward * with pState but not with pLast. If any more are identical, we * must */ fuseEquivStates( *pLast, *pState ); modified = true; } else { /* Last and this are different, do not set to merge them. Move * pLast to the current (it may be way behind from merging many * states) and pState forward one to consider the next pair. */ pLast = pState; } } delete[] statePtrs; return modified; } /** * \brief Minmimize by an approximation. * * Repeatedly tries to find states with transitions out to the same set of * states on the same set of keys until no more identical states can be found. * Does not produce the most minimial FSM possible. */ void FsmAp::minimizeApproximate() { /* While the last minimization round succeeded in compacting states, * continue to try to compact states. */ while ( true ) { bool modified = minimizeRound(); if ( ! modified ) break; } } /* Remove states that have no path to them from the start state. Recursively * traverses the graph marking states that have paths into them. Then removes * all states that did not get marked. */ void FsmAp::removeUnreachableStates() { /* Misfit accounting should be off and there should be no states on the * misfit list. */ assert( !misfitAccounting && misfitList.length() == 0 ); /* Mark all the states that can be reached * through the existing set of entry points. */ markReachableFromHere( startState ); for ( EntryMap::Iter en = entryPoints; en.lte(); en++ ) markReachableFromHere( en->value ); /* Delete all states that are not marked * and unmark the ones that are marked. */ StateAp *state = stateList.head; while ( state ) { StateAp *next = state->next; if ( state->stateBits & STB_ISMARKED ) state->stateBits &= ~ STB_ISMARKED; else { detachState( state ); stateList.detach( state ); delete state; } state = next; } } bool FsmAp::outListCovers( StateAp *state ) { /* Must be at least one range to cover. */ if ( state->outList.length() == 0 ) return false; /* The first must start at the lower bound. */ TransList::Iter trans = state->outList.first(); if ( keyOps->minKey < trans->lowKey ) return false; /* Loop starts at second el. */ trans.increment(); /* Loop checks lower against prev upper. */ for ( ; trans.lte(); trans++ ) { /* Lower end of the trans must be one greater than the * previous' high end. */ Key lowKey = trans->lowKey; lowKey.decrement(); if ( trans->prev->highKey < lowKey ) return false; } /* Require that the last range extends to the upper bound. */ trans = state->outList.last(); if ( trans->highKey < keyOps->maxKey ) return false; return true; } /* Remove states that that do not lead to a final states. Works recursivly traversing * the graph in reverse (starting from all final states) and marking seen states. Then * removes states that did not get marked. */ void FsmAp::removeDeadEndStates() { /* Misfit accounting should be off and there should be no states on the * misfit list. */ assert( !misfitAccounting && misfitList.length() == 0 ); /* Mark all states that have paths to the final states. */ StateAp **st = finStateSet.data; int nst = finStateSet.length(); for ( int i = 0; i < nst; i++, st++ ) markReachableFromHereReverse( *st ); /* Start state gets honorary marking. If the machine accepts nothing we * still want the start state to hang around. This must be done after the * recursive call on all the final states so that it does not cause the * start state in transitions to be skipped when the start state is * visited by the traversal. */ startState->stateBits |= STB_ISMARKED; /* Delete all states that are not marked * and unmark the ones that are marked. */ StateAp *state = stateList.head; while ( state != 0 ) { StateAp *next = state->next; if ( state->stateBits & STB_ISMARKED ) state->stateBits &= ~ STB_ISMARKED; else { detachState( state ); stateList.detach( state ); delete state; } state = next; } } /* Remove states on the misfit list. To work properly misfit accounting should * be on when this is called. The detaching of a state will likely cause * another misfit to be collected and it can then be removed. */ void FsmAp::removeMisfits() { while ( misfitList.length() > 0 ) { /* Get the first state. */ StateAp *state = misfitList.head; /* Detach and delete. */ detachState( state ); /* The state was previously on the misfit list and detaching can only * remove in transitions so the state must still be on the misfit * list. */ misfitList.detach( state ); delete state; } } /* Fuse src into dest because they have been deemed equivalent states. * Involves moving transitions into src to go into dest and invoking * callbacks. Src is deleted detached from the graph and deleted. */ void FsmAp::fuseEquivStates( StateAp *dest, StateAp *src ) { /* This would get ugly. */ assert( dest != src ); /* Cur is a duplicate. We can merge it with trail. */ inTransMove( dest, src ); detachState( src ); stateList.detach( src ); delete src; } void FsmAp::fuseUnmarkedPairs( MarkIndex &markIndex ) { StateAp *p = stateList.head, *nextP, *q; /* Definition: The primary state of an equivalence class is the first state * encounterd that belongs to the equivalence class. All equivalence * classes have primary state including equivalence classes with one state * in it. */ /* For each unmarked pair merge p into q and delete p. q is always the * primary state of it's equivalence class. We wouldn't have landed on it * here if it were not, because it would have been deleted. * * Proof that q is the primaray state of it's equivalence class: Assume q * is not the primary state of it's equivalence class, then it would be * merged into some state that came before it and thus p would be * equivalent to that state. But q is the first state that p is equivalent * to so we have a contradiction. */ /* Walk all unordered pairs of (p, q) where p != q. * The second depth of the walk stops before reaching p. This * gives us all unordered pairs of states (p, q) where p != q. */ while ( p != 0 ) { nextP = p->next; q = stateList.head; while ( q != p ) { /* If one of p or q is a final state then mark. */ if ( ! markIndex.isPairMarked( p->alg.stateNum, q->alg.stateNum ) ) { fuseEquivStates( q, p ); break; } q = q->next; } p = nextP; } } void FsmAp::fusePartitions( MinPartition *parts, int numParts ) { /* For each partition, fuse state 2, 3, ... into state 1. */ for ( int p = 0; p < numParts; p++ ) { /* Assume that there will always be at least one state. */ StateAp *first = parts[p].list.head, *toFuse = first->next; /* Put the first state back onto the main state list. Don't bother * removing it from the partition list first. */ stateList.append( first ); /* Fuse the rest of the state into the first. */ while ( toFuse != 0 ) { /* Save the next. We will trash it before it is needed. */ StateAp *next = toFuse->next; /* Put the state to be fused in to the first back onto the main * list before it is fuse. the graph. The state needs to be on * the main list for the detach from the graph to work. Don't * bother removing the state from the partition list first. We * need not maintain it. */ stateList.append( toFuse ); /* Now fuse to the first. */ fuseEquivStates( first, toFuse ); /* Go to the next that we saved before trashing the next pointer. */ toFuse = next; } /* We transfered the states from the partition list into the main list without * removing the states from the partition list first. Clean it up. */ parts[p].list.abandon(); } } /* Merge neighboring transitions go to the same state and have the same * transitions data. */ void FsmAp::compressTransitions() { for ( StateList::Iter st = stateList; st.lte(); st++ ) { if ( st->outList.length() > 1 ) { for ( TransList::Iter trans = st->outList, next = trans.next(); next.lte(); ) { Key nextLow = next->lowKey; nextLow.decrement(); if ( trans->highKey == nextLow && trans->toState == next->toState && CmpActionTable::compare( trans->actionTable, next->actionTable ) == 0 ) { trans->highKey = next->highKey; st->outList.detach( next ); detachTrans( next->fromState, next->toState, next ); delete next; next = trans.next(); } else { trans.increment(); next.increment(); } } } } } ragel-6.10/ragel/goflat.cpp0000664000175000017500000004452313065111230012527 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "goflat.h" #include "redfsm.h" #include "gendata.h" using std::endl; std::ostream &GoFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &GoFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &GoFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &GoFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &GoFlatCodeGen::TO_STATE_ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoFlatCodeGen::FROM_STATE_ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoFlatCodeGen::EOF_ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, true, false ); } } genLineDirective( out ); return out; } std::ostream &GoFlatCodeGen::ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoFlatCodeGen::FLAT_INDEX_OFFSET() { out << " "; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } /* Move the index offset ahead. */ if ( st->transList != 0 ) curIndOffset += keyOps->span( st->lowKey, st->highKey ); if ( st->defTrans != 0 ) curIndOffset += 1; } out << endl; return out; } std::ostream &GoFlatCodeGen::KEY_SPANS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->transList != 0 ) span = keyOps->span( st->lowKey, st->highKey ); out << span << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::TO_STATE_ACTIONS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::FROM_STATE_ACTIONS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::EOF_ACTIONS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::EOF_TRANS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::COND_KEYS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just cond low key and cond high key. */ out << KEY( st->condLowKey ) << ", "; out << KEY( st->condHighKey ) << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::COND_KEY_SPANS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->condList != 0 ) span = keyOps->span( st->condLowKey, st->condHighKey ); out << span << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::CONDS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->condList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->condList[pos] != 0 ) out << st->condList[pos]->condSpaceId + 1 << ", "; else out << "0, "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } } } out << endl; return out; } std::ostream &GoFlatCodeGen::COND_INDEX_OFFSET() { out << " "; int totalStateNum = 0; int curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } /* Move the index offset ahead. */ if ( st->condList != 0 ) curIndOffset += keyOps->span( st->condLowKey, st->condHighKey ); } out << endl; return out; } std::ostream &GoFlatCodeGen::KEYS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just low key and high key. */ out << KEY( st->lowKey ) << ", "; out << KEY( st->highKey ) << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::INDICIES() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->transList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->lowKey, st->highKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { out << st->transList[pos]->id << ", "; if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { out << st->defTrans->id << ", "; if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoFlatCodeGen::TRANS_TARGS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << " "; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id << ", "; if ( t < redFsm->transSet.length()-1 ) { if ( ++totalStates % IALL == 0 ) out << endl << " "; } } out << endl; delete[] transPtrs; return out; } std::ostream &GoFlatCodeGen::TRANS_ACTIONS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << " "; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); out << ", "; if ( t < redFsm->transSet.length()-1 ) { if ( ++totalAct % IALL == 0 ) out << endl << " "; } } out << endl; delete[] transPtrs; return out; } void GoFlatCodeGen::LOCATE_TRANS() { out << " _keys = " << CAST(INT(), vCS() + " << 1") << endl << " _inds = " << CAST(INT(), IO() + "[" + vCS() + "]") << endl << endl << " _slen = " << CAST(INT(), SP() + "[" + vCS() + "]") << endl << " if _slen > 0 && " << K() << "[_keys] <= " << GET_WIDE_KEY() << " && " << GET_WIDE_KEY() << " <= " << K() << "[_keys + 1]" << " {" << endl << " _trans = " << CAST(INT(), I() + "[_inds + " + CAST(INT(), GET_WIDE_KEY() + " - " + K() + "[_keys]") + "]") << endl << " } else {" << endl << " _trans = " << CAST(INT(), I() + "[_inds + _slen]") << endl << " }" << endl << endl; } void GoFlatCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << endl; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << endl; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << endl; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << endl; } STATE_IDS(); } void GoFlatCodeGen::COND_TRANSLATE() { out << " _widec = " << CAST(WIDE_ALPH_TYPE(), GET_KEY()) << endl; out << " _keys = " << CAST(INT(), vCS() + " << 1") << endl << " _conds = " << CAST(INT(), CO() + "[" + vCS() + "]") << endl << endl << " _slen = " << CAST(INT(), CSP() + "[" + vCS() + "]") << endl << " if _slen > 0 && " << CK() << "[_keys]" << " <= " << GET_WIDE_KEY() << " && " << GET_WIDE_KEY() << " <= " << CK() << "[_keys + 1] {" << endl << " _cond = " << CAST(INT(), C() + "[_conds + " + CAST(INT(), GET_WIDE_KEY() + " - " + CK() + "[_keys]") + "]") << endl << " } else {" << endl << " _cond = 0" << endl << " }" << endl << endl; out << " switch _cond {" << endl; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId + 1 << ":" << endl; out << TABS(2) << "_widec = " << KEY(condSpace->baseKey) << " + (" << CAST(WIDE_ALPH_TYPE(), GET_KEY()) << " - " << KEY(keyOps->minKey) << ")" << endl; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " {" << endl << " _widec += " << condValOffset << endl << " }" << endl; } } out << " }" << endl; } void GoFlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {" << endl << " var _slen " << INT() << endl; if ( redFsm->anyRegCurStateRef() ) out << " var _ps " << INT() << endl; out << " var _trans " << INT() << endl; if ( redFsm->anyConditions() ) out << " var _cond " << INT() << endl; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " var _acts " << INT() << endl << " var _nacts " << UINT() << endl; } out << " var _keys " << INT() << endl << " var _inds " << INT() << endl; if ( redFsm->anyConditions() ) { out << " var _conds " << INT() << endl << " var _widec " << WIDE_ALPH_TYPE() << endl; } out << endl; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " == " << PE() << " {" << endl << " goto _test_eof" << endl << " }" << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } out << "_resume:" << endl; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << CAST(INT(), FSA() + "[" + vCS() + "]") << endl << " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl << " for ; _nacts > 0; _nacts-- {" << endl << " _acts++" << endl << " switch " << A() << "[_acts - 1]" << " {" << endl; FROM_STATE_ACTION_SWITCH(2); out << " }" << endl << " }" << endl << endl; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) out << "_eof_trans:" << endl; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << endl; out << " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl << endl; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] == 0 {" << endl << " goto _again" << endl << " }" << endl << endl << " _acts = " << CAST(INT(), TA() + "[_trans]") << endl << " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl << " for ; _nacts > 0; _nacts-- {" << endl << " _acts++" << endl << " switch " << A() << "[_acts - 1]" << " {" << endl; ACTION_SWITCH(2); out << " }" << endl << " }" << endl << endl; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:" << endl; if ( redFsm->anyToStateActions() ) { out << " _acts = " << CAST(INT(), TSA() + "[" + vCS() + "]") << endl << " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl << " for ; _nacts > 0; _nacts-- {" << endl << " _acts++" << endl << " switch " << A() << "[_acts - 1]" << " {" << endl; TO_STATE_ACTION_SWITCH(2); out << " }" << endl << " }" << endl << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } if ( !noEnd ) { out << " if " << P() << "++; " << P() << " != " << PE() << " {" << endl << " goto _resume" << endl << " }" << endl; } else { out << " " << P() << "++" << endl << " goto _resume" << endl; } if ( testEofUsed ) out << " _test_eof: {}" << endl; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << " {" << endl; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0 {" << endl << " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl << " goto _eof_trans" << endl << " }" << endl; } if ( redFsm->anyEofActions() ) { out << " __acts := " << CAST(INT(), EA() + "[" + vCS() + "]") << endl << " __nacts := " << CAST(UINT(), A() + "[__acts]") << "; __acts++" << endl << " for ; __nacts > 0; __nacts-- {" << endl << " __acts++" << endl << " switch " << A() << "[__acts - 1]" << " {" << endl; EOF_ACTION_SWITCH(3); out << " }" << endl << " }" << endl; } out << " }" << endl << endl; } if ( outLabelUsed ) out << " _out: {}" << endl; out << " }" << endl; } ragel-6.10/ragel/gendata.cpp0000664000175000017500000007622613065111230012663 00000000000000/* * Copyright 2005-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "gendata.h" #include "ragel.h" #include /* * Code generators. */ #include "cstable.h" #include "csftable.h" #include "csflat.h" #include "csfflat.h" #include "csgoto.h" #include "csfgoto.h" #include "csipgoto.h" #include "cssplit.h" #include "cdtable.h" #include "cdftable.h" #include "cdflat.h" #include "cdfflat.h" #include "cdgoto.h" #include "cdfgoto.h" #include "cdipgoto.h" #include "cdsplit.h" #include "dotcodegen.h" #include "javacodegen.h" #include "gocodegen.h" #include "gotable.h" #include "goftable.h" #include "goflat.h" #include "gofflat.h" #include "gogoto.h" #include "gofgoto.h" #include "goipgoto.h" #include "mltable.h" #include "mlftable.h" #include "mlflat.h" #include "mlfflat.h" #include "mlgoto.h" #include "mlfgoto.h" #include "rubytable.h" #include "rubyftable.h" #include "rubyflat.h" #include "rubyfflat.h" #include "rbxgoto.h" string itoa( int i ) { char buf[16]; sprintf( buf, "%i", i ); return buf; } using std::cout; using std::cerr; using std::endl; /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *dotMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = new GraphvizDotGen(out); codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; /* For normal code generation we want a transition on every character so we never * end up in an undefined state. For graphviz this just clutters the * drawing so we turn it off. */ codeGen->wantComplete = false; return codeGen; } /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *cdMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = 0; switch ( hostLang->lang ) { case HostLang::C: switch ( codeStyle ) { case GenTables: codeGen = new CTabCodeGen(out); break; case GenFTables: codeGen = new CFTabCodeGen(out); break; case GenFlat: codeGen = new CFlatCodeGen(out); break; case GenFFlat: codeGen = new CFFlatCodeGen(out); break; case GenGoto: codeGen = new CGotoCodeGen(out); break; case GenFGoto: codeGen = new CFGotoCodeGen(out); break; case GenIpGoto: codeGen = new CIpGotoCodeGen(out); break; case GenSplit: codeGen = new CSplitCodeGen(out); break; } break; case HostLang::D: switch ( codeStyle ) { case GenTables: codeGen = new DTabCodeGen(out); break; case GenFTables: codeGen = new DFTabCodeGen(out); break; case GenFlat: codeGen = new DFlatCodeGen(out); break; case GenFFlat: codeGen = new DFFlatCodeGen(out); break; case GenGoto: codeGen = new DGotoCodeGen(out); break; case GenFGoto: codeGen = new DFGotoCodeGen(out); break; case GenIpGoto: codeGen = new DIpGotoCodeGen(out); break; case GenSplit: codeGen = new DSplitCodeGen(out); break; } break; case HostLang::D2: switch ( codeStyle ) { case GenTables: codeGen = new D2TabCodeGen(out); break; case GenFTables: codeGen = new D2FTabCodeGen(out); break; case GenFlat: codeGen = new D2FlatCodeGen(out); break; case GenFFlat: codeGen = new D2FFlatCodeGen(out); break; case GenGoto: codeGen = new D2GotoCodeGen(out); break; case GenFGoto: codeGen = new D2FGotoCodeGen(out); break; case GenIpGoto: codeGen = new D2IpGotoCodeGen(out); break; case GenSplit: codeGen = new D2SplitCodeGen(out); break; } break; default: break; } codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; return codeGen; } /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *javaMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = new JavaTabCodeGen(out); codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; return codeGen; } /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *goMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = 0; switch ( codeStyle ) { case GenTables: codeGen = new GoTabCodeGen(out); break; case GenFTables: codeGen = new GoFTabCodeGen(out); break; case GenFlat: codeGen = new GoFlatCodeGen(out); break; case GenFFlat: codeGen = new GoFFlatCodeGen(out); break; case GenGoto: codeGen = new GoGotoCodeGen(out); break; case GenFGoto: codeGen = new GoFGotoCodeGen(out); break; case GenIpGoto: codeGen = new GoIpGotoCodeGen(out); break; default: cerr << "Invalid output style, only -T0, -T1, -F0, -F1, -G0, -G1 and -G2 are supported for Go.\n"; exit(1); } codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; return codeGen; } /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *rubyMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = 0; switch ( codeStyle ) { case GenTables: codeGen = new RubyTabCodeGen(out); break; case GenFTables: codeGen = new RubyFTabCodeGen(out); break; case GenFlat: codeGen = new RubyFlatCodeGen(out); break; case GenFFlat: codeGen = new RubyFFlatCodeGen(out); break; case GenGoto: if ( rubyImpl == Rubinius ) { codeGen = new RbxGotoCodeGen(out); } else { cerr << "Goto style is still _very_ experimental " "and only supported using Rubinius.\n" "You may want to enable the --rbx flag " " to give it a try.\n"; exit(1); } break; default: cout << "Invalid code style\n"; exit(1); break; } codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; return codeGen; } /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *csharpMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = 0; switch ( codeStyle ) { case GenTables: codeGen = new CSharpTabCodeGen(out); break; case GenFTables: codeGen = new CSharpFTabCodeGen(out); break; case GenFlat: codeGen = new CSharpFlatCodeGen(out); break; case GenFFlat: codeGen = new CSharpFFlatCodeGen(out); break; case GenGoto: codeGen = new CSharpGotoCodeGen(out); break; case GenFGoto: codeGen = new CSharpFGotoCodeGen(out); break; case GenIpGoto: codeGen = new CSharpIpGotoCodeGen(out); break; case GenSplit: codeGen = new CSharpSplitCodeGen(out); break; } codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; return codeGen; } /* Invoked by the parser when a ragel definition is opened. */ CodeGenData *ocamlMakeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *codeGen = 0; switch ( codeStyle ) { case GenTables: codeGen = new OCamlTabCodeGen(out); break; case GenFTables: codeGen = new OCamlFTabCodeGen(out); break; case GenFlat: codeGen = new OCamlFlatCodeGen(out); break; case GenFFlat: codeGen = new OCamlFFlatCodeGen(out); break; case GenGoto: codeGen = new OCamlGotoCodeGen(out); break; case GenFGoto: codeGen = new OCamlFGotoCodeGen(out); break; default: cerr << "I only support the -T0 -T1 -F0 -F1 -G0 and -G1 output styles for OCaml.\n"; exit(1); } codeGen->sourceFileName = sourceFileName; codeGen->fsmName = fsmName; return codeGen; } CodeGenData *makeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ) { CodeGenData *cgd = 0; if ( generateDot ) cgd = dotMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangC ) cgd = cdMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangD ) cgd = cdMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangD2 ) cgd = cdMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangGo ) cgd = goMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangJava ) cgd = javaMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangRuby ) cgd = rubyMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangCSharp ) cgd = csharpMakeCodeGen( sourceFileName, fsmName, out ); else if ( hostLang == &hostLangOCaml ) cgd = ocamlMakeCodeGen( sourceFileName, fsmName, out ); return cgd; } void lineDirective( ostream &out, const char *fileName, int line ) { if ( !generateDot ) { if ( hostLang == &hostLangC ) cdLineDirective( out, fileName, line ); else if ( hostLang == &hostLangD ) cdLineDirective( out, fileName, line ); else if ( hostLang == &hostLangD2 ) cdLineDirective( out, fileName, line ); else if ( hostLang == &hostLangGo ) goLineDirective( out, fileName, line ); else if ( hostLang == &hostLangJava ) javaLineDirective( out, fileName, line ); else if ( hostLang == &hostLangRuby ) rubyLineDirective( out, fileName, line ); else if ( hostLang == &hostLangCSharp ) csharpLineDirective( out, fileName, line ); else if ( hostLang == &hostLangOCaml ) ocamlLineDirective( out, fileName, line ); } } void genLineDirective( ostream &out ) { std::streambuf *sbuf = out.rdbuf(); output_filter *filter = static_cast(sbuf); lineDirective( out, filter->fileName, filter->line + 1 ); } /* Total error count. */ /* int gblErrorCount = 0; */ CodeGenData::CodeGenData( ostream &out ) : sourceFileName(0), fsmName(0), out(out), redFsm(0), allActions(0), allActionTables(0), allConditions(0), allCondSpaces(0), allStates(0), nameIndex(0), startState(-1), errState(-1), getKeyExpr(0), accessExpr(0), prePushExpr(0), postPopExpr(0), pExpr(0), peExpr(0), eofExpr(0), csExpr(0), topExpr(0), stackExpr(0), actExpr(0), tokstartExpr(0), tokendExpr(0), dataExpr(0), wantComplete(true), hasLongestMatch(false), noEnd(false), noPrefix(false), noFinal(false), noError(false), noEntry(false), noCS(false) {} void CodeGenData::createMachine() { redFsm = new RedFsmAp(); } void CodeGenData::initActionList( unsigned long length ) { allActions = new GenAction[length]; for ( unsigned long a = 0; a < length; a++ ) actionList.append( allActions+a ); } void CodeGenData::newAction( int anum, const char *name, const InputLoc &loc, GenInlineList *inlineList ) { allActions[anum].actionId = anum; allActions[anum].name = name; allActions[anum].loc = loc; allActions[anum].inlineList = inlineList; } void CodeGenData::initActionTableList( unsigned long length ) { allActionTables = new RedAction[length]; } void CodeGenData::initStateList( unsigned long length ) { allStates = new RedStateAp[length]; for ( unsigned long s = 0; s < length; s++ ) redFsm->stateList.append( allStates+s ); /* We get the start state as an offset, set the pointer now. */ if ( startState >= 0 ) redFsm->startState = allStates + startState; if ( errState >= 0 ) redFsm->errState = allStates + errState; for ( EntryIdVect::Iter en = entryPointIds; en.lte(); en++ ) redFsm->entryPoints.insert( allStates + *en ); /* The nextStateId is no longer used to assign state ids (they come in set * from the frontend now), however generation code still depends on it. * Should eventually remove this variable. */ redFsm->nextStateId = redFsm->stateList.length(); } void CodeGenData::setStartState( unsigned long startState ) { this->startState = startState; } void CodeGenData::setErrorState( unsigned long errState ) { this->errState = errState; } void CodeGenData::addEntryPoint( char *name, unsigned long entryState ) { entryPointIds.append( entryState ); entryPointNames.append( name ); } void CodeGenData::initTransList( int snum, unsigned long length ) { /* Could preallocate the out range to save time growing it. For now do * nothing. */ } void CodeGenData::newTrans( int snum, int tnum, Key lowKey, Key highKey, long targ, long action ) { /* Get the current state and range. */ RedStateAp *curState = allStates + snum; RedTransList &destRange = curState->outRange; if ( curState == redFsm->errState ) return; /* Make the new transitions. */ RedStateAp *targState = targ >= 0 ? (allStates + targ) : wantComplete ? redFsm->getErrorState() : 0; RedAction *actionTable = action >= 0 ? (allActionTables + action) : 0; RedTransAp *trans = redFsm->allocateTrans( targState, actionTable ); RedTransEl transEl( lowKey, highKey, trans ); if ( wantComplete ) { /* If the machine is to be complete then we need to fill any gaps with * the error transitions. */ if ( destRange.length() == 0 ) { /* Range is currently empty. */ if ( keyOps->minKey < lowKey ) { /* The first range doesn't start at the low end. */ Key fillHighKey = lowKey; fillHighKey.decrement(); /* Create the filler with the state's error transition. */ RedTransEl newTel( keyOps->minKey, fillHighKey, redFsm->getErrorTrans() ); destRange.append( newTel ); } } else { /* The range list is not empty, get the the last range. */ RedTransEl *last = &destRange[destRange.length()-1]; Key nextKey = last->highKey; nextKey.increment(); if ( nextKey < lowKey ) { /* There is a gap to fill. Make the high key. */ Key fillHighKey = lowKey; fillHighKey.decrement(); /* Create the filler with the state's error transtion. */ RedTransEl newTel( nextKey, fillHighKey, redFsm->getErrorTrans() ); destRange.append( newTel ); } } } /* Filler taken care of. Append the range. */ destRange.append( RedTransEl( lowKey, highKey, trans ) ); } void CodeGenData::finishTransList( int snum ) { /* Get the current state and range. */ RedStateAp *curState = allStates + snum; RedTransList &destRange = curState->outRange; if ( curState == redFsm->errState ) return; /* If building a complete machine we may need filler on the end. */ if ( wantComplete ) { /* Check if there are any ranges already. */ if ( destRange.length() == 0 ) { /* Fill with the whole alphabet. */ /* Add the range on the lower and upper bound. */ RedTransEl newTel( keyOps->minKey, keyOps->maxKey, redFsm->getErrorTrans() ); destRange.append( newTel ); } else { /* Get the last and check for a gap on the end. */ RedTransEl *last = &destRange[destRange.length()-1]; if ( last->highKey < keyOps->maxKey ) { /* Make the high key. */ Key fillLowKey = last->highKey; fillLowKey.increment(); /* Create the new range with the error trans and append it. */ RedTransEl newTel( fillLowKey, keyOps->maxKey, redFsm->getErrorTrans() ); destRange.append( newTel ); } } } } void CodeGenData::setId( int snum, int id ) { RedStateAp *curState = allStates + snum; curState->id = id; } void CodeGenData::setFinal( int snum ) { RedStateAp *curState = allStates + snum; curState->isFinal = true; } void CodeGenData::setStateActions( int snum, long toStateAction, long fromStateAction, long eofAction ) { RedStateAp *curState = allStates + snum; if ( toStateAction >= 0 ) curState->toStateAction = allActionTables + toStateAction; if ( fromStateAction >= 0 ) curState->fromStateAction = allActionTables + fromStateAction; if ( eofAction >= 0 ) curState->eofAction = allActionTables + eofAction; } void CodeGenData::setEofTrans( int snum, long eofTarget, long actId ) { RedStateAp *curState = allStates + snum; RedStateAp *targState = allStates + eofTarget; RedAction *eofAct = allActionTables + actId; curState->eofTrans = redFsm->allocateTrans( targState, eofAct ); } void CodeGenData::resolveTargetStates( GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: case GenInlineItem::Next: case GenInlineItem::Entry: item->targState = allStates + item->targId; break; default: break; } if ( item->children != 0 ) resolveTargetStates( item->children ); } } void CodeGenData::closeMachine() { for ( GenActionList::Iter a = actionList; a.lte(); a++ ) resolveTargetStates( a->inlineList ); /* Note that even if we want a complete graph we do not give the error * state a default transition. All machines break out of the processing * loop when in the error state. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( GenStateCondList::Iter sci = st->stateCondList; sci.lte(); sci++ ) st->stateCondVect.append( sci ); } } bool CodeGenData::setAlphType( const char *data ) { HostType *alphType = findAlphTypeInternal( data ); if ( alphType == 0 ) return false; thisKeyOps.setAlphType( alphType ); return true; } void CodeGenData::initCondSpaceList( ulong length ) { allCondSpaces = new GenCondSpace[length]; for ( ulong c = 0; c < length; c++ ) condSpaceList.append( allCondSpaces + c ); } void CodeGenData::newCondSpace( int cnum, int condSpaceId, Key baseKey ) { GenCondSpace *cond = allCondSpaces + cnum; cond->condSpaceId = condSpaceId; cond->baseKey = baseKey; } void CodeGenData::condSpaceItem( int cnum, long condActionId ) { GenCondSpace *cond = allCondSpaces + cnum; cond->condSet.append( allActions + condActionId ); } void CodeGenData::initStateCondList( int snum, ulong length ) { /* Could preallocate these, as we could with transitions. */ } void CodeGenData::addStateCond( int snum, Key lowKey, Key highKey, long condNum ) { RedStateAp *curState = allStates + snum; /* Create the new state condition. */ GenStateCond *stateCond = new GenStateCond; stateCond->lowKey = lowKey; stateCond->highKey = highKey; /* Assign it a cond space. */ GenCondSpace *condSpace = allCondSpaces + condNum; stateCond->condSpace = condSpace; curState->stateCondList.append( stateCond ); } GenCondSpace *CodeGenData::findCondSpace( Key lowKey, Key highKey ) { for ( CondSpaceList::Iter cs = condSpaceList; cs.lte(); cs++ ) { Key csHighKey = cs->baseKey; csHighKey += keyOps->alphSize() * (1 << cs->condSet.length()); if ( lowKey >= cs->baseKey && highKey <= csHighKey ) return cs; } return 0; } Condition *CodeGenData::findCondition( Key key ) { for ( ConditionList::Iter cond = conditionList; cond.lte(); cond++ ) { Key upperKey = cond->baseKey + (1 << cond->condSet.length()); if ( cond->baseKey <= key && key <= upperKey ) return cond; } return 0; } Key CodeGenData::findMaxKey() { Key maxKey = keyOps->maxKey; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { assert( st->outSingle.length() == 0 ); assert( st->defTrans == 0 ); long rangeLen = st->outRange.length(); if ( rangeLen > 0 ) { Key highKey = st->outRange[rangeLen-1].highKey; if ( highKey > maxKey ) maxKey = highKey; } } return maxKey; } void CodeGenData::findFinalActionRefs() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Rerence count out of single transitions. */ for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 ) { rtel->value->action->numTransRefs += 1; for ( GenActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } } /* Reference count out of range transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 ) { rtel->value->action->numTransRefs += 1; for ( GenActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } } /* Reference count default transition. */ if ( st->defTrans != 0 && st->defTrans->action != 0 ) { st->defTrans->action->numTransRefs += 1; for ( GenActionTable::Iter item = st->defTrans->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } /* Reference count eof transitions. */ if ( st->eofTrans != 0 && st->eofTrans->action != 0 ) { st->eofTrans->action->numTransRefs += 1; for ( GenActionTable::Iter item = st->eofTrans->action->key; item.lte(); item++ ) item->value->numTransRefs += 1; } /* Reference count to state actions. */ if ( st->toStateAction != 0 ) { st->toStateAction->numToStateRefs += 1; for ( GenActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) item->value->numToStateRefs += 1; } /* Reference count from state actions. */ if ( st->fromStateAction != 0 ) { st->fromStateAction->numFromStateRefs += 1; for ( GenActionTable::Iter item = st->fromStateAction->key; item.lte(); item++ ) item->value->numFromStateRefs += 1; } /* Reference count EOF actions. */ if ( st->eofAction != 0 ) { st->eofAction->numEofRefs += 1; for ( GenActionTable::Iter item = st->eofAction->key; item.lte(); item++ ) item->value->numEofRefs += 1; } } } void CodeGenData::analyzeAction( GenAction *act, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { /* Only consider actions that are referenced. */ if ( act->numRefs() > 0 ) { if ( item->type == GenInlineItem::Goto || item->type == GenInlineItem::GotoExpr ) redFsm->bAnyActionGotos = true; else if ( item->type == GenInlineItem::Call || item->type == GenInlineItem::CallExpr ) redFsm->bAnyActionCalls = true; else if ( item->type == GenInlineItem::Ret ) redFsm->bAnyActionRets = true; if ( item->type == GenInlineItem::CallExpr || item->type == GenInlineItem::GotoExpr ) redFsm->bAnyActionByValControl = true; } /* Check for various things in regular actions. */ if ( act->numTransRefs > 0 || act->numToStateRefs > 0 || act->numFromStateRefs > 0 ) { /* Any returns in regular actions? */ if ( item->type == GenInlineItem::Ret ) redFsm->bAnyRegActionRets = true; /* Any next statements in the regular actions? */ if ( item->type == GenInlineItem::Next || item->type == GenInlineItem::NextExpr ) redFsm->bAnyRegNextStmt = true; /* Any by value control in regular actions? */ if ( item->type == GenInlineItem::CallExpr || item->type == GenInlineItem::GotoExpr ) redFsm->bAnyRegActionByValControl = true; /* Any references to the current state in regular actions? */ if ( item->type == GenInlineItem::Curs ) redFsm->bAnyRegCurStateRef = true; if ( item->type == GenInlineItem::Break ) redFsm->bAnyRegBreak = true; } if ( item->children != 0 ) analyzeAction( act, item->children ); } } void CodeGenData::analyzeActionList( RedAction *redAct, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { /* Any next statements in the action table? */ if ( item->type == GenInlineItem::Next || item->type == GenInlineItem::NextExpr ) redAct->bAnyNextStmt = true; /* Any references to the current state. */ if ( item->type == GenInlineItem::Curs ) redAct->bAnyCurStateRef = true; if ( item->type == GenInlineItem::Break ) redAct->bAnyBreakStmt = true; if ( item->children != 0 ) analyzeActionList( redAct, item->children ); } } /* Assign ids to referenced actions. */ void CodeGenData::assignActionIds() { int nextActionId = 0; for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Only ever interested in referenced actions. */ if ( act->numRefs() > 0 ) act->actionId = nextActionId++; } } void CodeGenData::setValueLimits() { redFsm->maxSingleLen = 0; redFsm->maxRangeLen = 0; redFsm->maxKeyOffset = 0; redFsm->maxIndexOffset = 0; redFsm->maxActListId = 0; redFsm->maxActionLoc = 0; redFsm->maxActArrItem = 0; redFsm->maxSpan = 0; redFsm->maxCondSpan = 0; redFsm->maxFlatIndexOffset = 0; redFsm->maxCondOffset = 0; redFsm->maxCondLen = 0; redFsm->maxCondSpaceId = 0; redFsm->maxCondIndexOffset = 0; /* In both of these cases the 0 index is reserved for no value, so the max * is one more than it would be if they started at 0. */ redFsm->maxIndex = redFsm->transSet.length(); redFsm->maxCond = condSpaceList.length(); /* The nextStateId - 1 is the last state id assigned. */ redFsm->maxState = redFsm->nextStateId - 1; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { if ( csi->condSpaceId > redFsm->maxCondSpaceId ) redFsm->maxCondSpaceId = csi->condSpaceId; } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Maximum cond length. */ if ( st->stateCondList.length() > redFsm->maxCondLen ) redFsm->maxCondLen = st->stateCondList.length(); /* Maximum single length. */ if ( st->outSingle.length() > redFsm->maxSingleLen ) redFsm->maxSingleLen = st->outSingle.length(); /* Maximum range length. */ if ( st->outRange.length() > redFsm->maxRangeLen ) redFsm->maxRangeLen = st->outRange.length(); /* The key offset index offset for the state after last is not used, skip it.. */ if ( ! st.last() ) { redFsm->maxCondOffset += st->stateCondList.length(); redFsm->maxKeyOffset += st->outSingle.length() + st->outRange.length()*2; redFsm->maxIndexOffset += st->outSingle.length() + st->outRange.length() + 2; } /* Max cond span. */ if ( st->condList != 0 ) { unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); if ( span > redFsm->maxCondSpan ) redFsm->maxCondSpan = span; } /* Max key span. */ if ( st->transList != 0 ) { unsigned long long span = keyOps->span( st->lowKey, st->highKey ); if ( span > redFsm->maxSpan ) redFsm->maxSpan = span; } /* Max cond index offset. */ if ( ! st.last() ) { if ( st->condList != 0 ) redFsm->maxCondIndexOffset += keyOps->span( st->condLowKey, st->condHighKey ); } /* Max flat index offset. */ if ( ! st.last() ) { if ( st->transList != 0 ) redFsm->maxFlatIndexOffset += keyOps->span( st->lowKey, st->highKey ); redFsm->maxFlatIndexOffset += 1; } } for ( GenActionTableMap::Iter at = redFsm->actionMap; at.lte(); at++ ) { /* Maximum id of action lists. */ if ( at->actListId+1 > redFsm->maxActListId ) redFsm->maxActListId = at->actListId+1; /* Maximum location of items in action array. */ if ( at->location+1 > redFsm->maxActionLoc ) redFsm->maxActionLoc = at->location+1; /* Maximum values going into the action array. */ if ( at->key.length() > redFsm->maxActArrItem ) redFsm->maxActArrItem = at->key.length(); for ( GenActionTable::Iter item = at->key; item.lte(); item++ ) { if ( item->value->actionId > redFsm->maxActArrItem ) redFsm->maxActArrItem = item->value->actionId; } } } /* Gather various info on the machine. */ void CodeGenData::analyzeMachine() { /* Find the true count of action references. */ findFinalActionRefs(); /* Check if there are any calls in action code. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Record the occurrence of various kinds of actions. */ if ( act->numToStateRefs > 0 ) redFsm->bAnyToStateActions = true; if ( act->numFromStateRefs > 0 ) redFsm->bAnyFromStateActions = true; if ( act->numEofRefs > 0 ) redFsm->bAnyEofActions = true; if ( act->numTransRefs > 0 ) redFsm->bAnyRegActions = true; /* Recurse through the action's parse tree looking for various things. */ analyzeAction( act, act->inlineList ); } /* Analyze reduced action lists. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { for ( GenActionTable::Iter act = redAct->key; act.lte(); act++ ) analyzeActionList( redAct, act->value->inlineList ); } /* Find states that have transitions with actions that have next * statements. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Check any actions out of outSinge. */ for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; } /* Check any actions out of outRange. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; } /* Check any action out of default. */ if ( st->defTrans != 0 && st->defTrans->action != 0 && st->defTrans->action->anyCurStateRef() ) st->bAnyRegCurStateRef = true; if ( st->stateCondList.length() > 0 ) redFsm->bAnyConditions = true; if ( st->eofTrans != 0 ) redFsm->bAnyEofTrans = true; } /* Assign ids to actions that are referenced. */ assignActionIds(); /* Set the maximums of various values used for deciding types. */ setValueLimits(); } void CodeGenData::write_option_error( InputLoc &loc, char *arg ) { source_warning(loc) << "unrecognized write option \"" << arg << "\"" << endl; } /* returns true if the following section should generate line directives. */ bool CodeGenData::writeStatement( InputLoc &loc, int nargs, char **args ) { bool followLineDirective = false; if ( strcmp( args[0], "data" ) == 0 ) { out << '\n'; genLineDirective( out ); followLineDirective = true; for ( int i = 1; i < nargs; i++ ) { if ( strcmp( args[i], "noerror" ) == 0 ) noError = true; else if ( strcmp( args[i], "noprefix" ) == 0 ) noPrefix = true; else if ( strcmp( args[i], "nofinal" ) == 0 ) noFinal = true; else if ( strcmp( args[i], "noentry" ) == 0 ) noEntry = true; else write_option_error( loc, args[i] ); } writeData(); } else if ( strcmp( args[0], "init" ) == 0 ) { out << '\n'; genLineDirective( out ); followLineDirective = true; for ( int i = 1; i < nargs; i++ ) { if ( strcmp( args[i], "nocs" ) == 0 ) noCS = true; else write_option_error( loc, args[i] ); } writeInit(); } else if ( strcmp( args[0], "exec" ) == 0 ) { out << '\n'; genLineDirective( out ); followLineDirective = true; for ( int i = 1; i < nargs; i++ ) { if ( strcmp( args[i], "noend" ) == 0 ) noEnd = true; else write_option_error( loc, args[i] ); } writeExec(); } else if ( strcmp( args[0], "exports" ) == 0 ) { out << '\n'; genLineDirective( out ); followLineDirective = true; for ( int i = 1; i < nargs; i++ ) write_option_error( loc, args[i] ); writeExports(); } else if ( strcmp( args[0], "start" ) == 0 ) { for ( int i = 1; i < nargs; i++ ) write_option_error( loc, args[i] ); writeStart(); } else if ( strcmp( args[0], "first_final" ) == 0 ) { for ( int i = 1; i < nargs; i++ ) write_option_error( loc, args[i] ); writeFirstFinal(); } else if ( strcmp( args[0], "error" ) == 0 ) { for ( int i = 1; i < nargs; i++ ) write_option_error( loc, args[i] ); writeError(); } else { /* EMIT An error here. */ source_error(loc) << "unrecognized write command \"" << args[0] << "\"" << endl; } return followLineDirective; } ostream &CodeGenData::source_warning( const InputLoc &loc ) { cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: "; return cerr; } ostream &CodeGenData::source_error( const InputLoc &loc ) { gblErrorCount += 1; assert( sourceFileName != 0 ); cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": "; return cerr; } ragel-6.10/ragel/fsmgraph.h0000664000175000017500000012277413065111230012534 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _FSMGRAPH_H #define _FSMGRAPH_H #include "config.h" #include #include #include #include "common.h" #include "vector.h" #include "bstset.h" #include "compare.h" #include "avltree.h" #include "dlist.h" #include "bstmap.h" #include "sbstmap.h" #include "sbstset.h" #include "sbsttable.h" #include "avlset.h" #include "avlmap.h" #include "ragel.h" //#define LOG_CONDS /* Flags that control merging. */ #define STB_GRAPH1 0x01 #define STB_GRAPH2 0x02 #define STB_BOTH 0x03 #define STB_ISFINAL 0x04 #define STB_ISMARKED 0x08 #define STB_ONLIST 0x10 using std::ostream; struct TransAp; struct StateAp; struct FsmAp; struct Action; struct LongestMatchPart; struct LengthDef; /* State list element for unambiguous access to list element. */ struct FsmListEl { StateAp *prev, *next; }; /* This is the marked index for a state pair. Used in minimization. It keeps * track of whether or not the state pair is marked. */ struct MarkIndex { MarkIndex(int states); ~MarkIndex(); void markPair(int state1, int state2); bool isPairMarked(int state1, int state2); private: int numStates; bool *array; }; extern KeyOps *keyOps; /* Transistion Action Element. */ typedef SBstMapEl< int, Action* > ActionTableEl; /* Nodes in the tree that use this action. */ struct NameInst; struct InlineList; typedef Vector ActionRefs; /* Element in list of actions. Contains the string for the code to exectute. */ struct Action : public DListEl, public AvlTreeEl { public: Action( const InputLoc &loc, const char *name, InlineList *inlineList, int condId ) : loc(loc), name(name), inlineList(inlineList), actionId(-1), numTransRefs(0), numToStateRefs(0), numFromStateRefs(0), numEofRefs(0), numCondRefs(0), anyCall(false), isLmAction(false), condId(condId) { } /* Key for action dictionary. */ const char *getKey() const { return name; } /* Data collected during parse. */ InputLoc loc; const char *name; InlineList *inlineList; int actionId; void actionName( ostream &out ) { if ( name != 0 ) out << name; else out << loc.line << ":" << loc.col; } /* Places in the input text that reference the action. */ ActionRefs actionRefs; /* Number of references in the final machine. */ int numRefs() { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; } int numTransRefs; int numToStateRefs; int numFromStateRefs; int numEofRefs; int numCondRefs; bool anyCall; bool isLmAction; int condId; }; struct CmpCondId { static inline int compare( const Action *cond1, const Action *cond2 ) { if ( cond1->condId < cond2->condId ) return -1; else if ( cond1->condId > cond2->condId ) return 1; return 0; } }; /* A list of actions. */ typedef DList ActionList; typedef AvlTree ActionDict; /* Structure for reverse action mapping. */ struct RevActionMapEl { char *name; InputLoc location; }; /* Transition Action Table. */ struct ActionTable : public SBstMap< int, Action*, CmpOrd > { void setAction( int ordering, Action *action ); void setActions( int *orderings, Action **actions, int nActs ); void setActions( const ActionTable &other ); bool hasAction( Action *action ); }; typedef SBstSet< Action*, CmpOrd > ActionSet; typedef CmpSTable< Action*, CmpOrd > CmpActionSet; /* Transistion Action Element. */ typedef SBstMapEl< int, LongestMatchPart* > LmActionTableEl; /* Transition Action Table. */ struct LmActionTable : public SBstMap< int, LongestMatchPart*, CmpOrd > { void setAction( int ordering, LongestMatchPart *action ); void setActions( const LmActionTable &other ); }; /* Compare of a whole action table element (key & value). */ struct CmpActionTableEl { static int compare( const ActionTableEl &action1, const ActionTableEl &action2 ) { if ( action1.key < action2.key ) return -1; else if ( action1.key > action2.key ) return 1; else if ( action1.value < action2.value ) return -1; else if ( action1.value > action2.value ) return 1; return 0; } }; /* Compare for ActionTable. */ typedef CmpSTable< ActionTableEl, CmpActionTableEl > CmpActionTable; /* Compare of a whole lm action table element (key & value). */ struct CmpLmActionTableEl { static int compare( const LmActionTableEl &lmAction1, const LmActionTableEl &lmAction2 ) { if ( lmAction1.key < lmAction2.key ) return -1; else if ( lmAction1.key > lmAction2.key ) return 1; else if ( lmAction1.value < lmAction2.value ) return -1; else if ( lmAction1.value > lmAction2.value ) return 1; return 0; } }; /* Compare for ActionTable. */ typedef CmpSTable< LmActionTableEl, CmpLmActionTableEl > CmpLmActionTable; /* Action table element for error action tables. Adds the encoding of transfer * point. */ struct ErrActionTableEl { ErrActionTableEl( Action *action, int ordering, int transferPoint ) : ordering(ordering), action(action), transferPoint(transferPoint) { } /* Ordering and id of the action embedding. */ int ordering; Action *action; /* Id of point of transfere from Error action table to transtions and * eofActionTable. */ int transferPoint; int getKey() const { return ordering; } }; struct ErrActionTable : public SBstTable< ErrActionTableEl, int, CmpOrd > { void setAction( int ordering, Action *action, int transferPoint ); void setActions( const ErrActionTable &other ); }; /* Compare of an error action table element (key & value). */ struct CmpErrActionTableEl { static int compare( const ErrActionTableEl &action1, const ErrActionTableEl &action2 ) { if ( action1.ordering < action2.ordering ) return -1; else if ( action1.ordering > action2.ordering ) return 1; else if ( action1.action < action2.action ) return -1; else if ( action1.action > action2.action ) return 1; else if ( action1.transferPoint < action2.transferPoint ) return -1; else if ( action1.transferPoint > action2.transferPoint ) return 1; return 0; } }; /* Compare for ErrActionTable. */ typedef CmpSTable< ErrActionTableEl, CmpErrActionTableEl > CmpErrActionTable; /* Descibe a priority, shared among PriorEls. * Has key and whether or not used. */ struct PriorDesc { int key; int priority; }; /* Element in the arrays of priorities for transitions and arrays. Ordering is * unique among instantiations of machines, desc is shared. */ struct PriorEl { PriorEl( int ordering, PriorDesc *desc ) : ordering(ordering), desc(desc) { } int ordering; PriorDesc *desc; }; /* Compare priority elements, which are ordered by the priority descriptor * key. */ struct PriorElCmp { static inline int compare( const PriorEl &pel1, const PriorEl &pel2 ) { if ( pel1.desc->key < pel2.desc->key ) return -1; else if ( pel1.desc->key > pel2.desc->key ) return 1; else return 0; } }; /* Priority Table. */ struct PriorTable : public SBstSet< PriorEl, PriorElCmp > { void setPrior( int ordering, PriorDesc *desc ); void setPriors( const PriorTable &other ); }; /* Compare of prior table elements for distinguising state data. */ struct CmpPriorEl { static inline int compare( const PriorEl &pel1, const PriorEl &pel2 ) { if ( pel1.desc < pel2.desc ) return -1; else if ( pel1.desc > pel2.desc ) return 1; else if ( pel1.ordering < pel2.ordering ) return -1; else if ( pel1.ordering > pel2.ordering ) return 1; return 0; } }; /* Compare of PriorTable distinguising state data. Using a compare of the * pointers is a little more strict than it needs be. It requires that * prioritiy tables have the exact same set of priority assignment operators * (from the input lang) to be considered equal. * * Really only key-value pairs need be tested and ordering be merged. However * this would require that in the fuseing of states, priority descriptors be * chosen for the new fused state based on priority. Since the out transition * lists and ranges aren't necessarily going to line up, this is more work for * little gain. Final compression resets all priorities first, so this would * only be useful for compression at every operator, which is only an * undocumented test feature. */ typedef CmpSTable CmpPriorTable; /* Plain action list that imposes no ordering. */ typedef Vector TransFuncList; /* Comparison for TransFuncList. */ typedef CmpTable< int, CmpOrd > TransFuncListCompare; /* Transition class that implements actions and priorities. */ struct TransAp { TransAp() : fromState(0), toState(0) {} TransAp( const TransAp &other ) : lowKey(other.lowKey), highKey(other.highKey), fromState(0), toState(0), actionTable(other.actionTable), priorTable(other.priorTable), lmActionTable(other.lmActionTable) {} Key lowKey, highKey; StateAp *fromState; StateAp *toState; /* Pointers for outlist. */ TransAp *prev, *next; /* Pointers for in-list. */ TransAp *ilprev, *ilnext; /* The function table and priority for the transition. */ ActionTable actionTable; PriorTable priorTable; LmActionTable lmActionTable; }; /* In transition list. Like DList except only has head pointers, which is all * that is required. Insertion and deletion is handled by the graph. This * class provides the iterator of a single list. */ struct TransInList { TransInList() : head(0) { } TransAp *head; struct Iter { /* Default construct. */ Iter() : ptr(0) { } /* Construct, assign from a list. */ Iter( const TransInList &il ) : ptr(il.head) { } Iter &operator=( const TransInList &dl ) { ptr = dl.head; return *this; } /* At the end */ bool lte() const { return ptr != 0; } bool end() const { return ptr == 0; } /* At the first, last element. */ bool first() const { return ptr && ptr->ilprev == 0; } bool last() const { return ptr && ptr->ilnext == 0; } /* Cast, dereference, arrow ops. */ operator TransAp*() const { return ptr; } TransAp &operator *() const { return *ptr; } TransAp *operator->() const { return ptr; } /* Increment, decrement. */ inline void operator++(int) { ptr = ptr->ilnext; } inline void operator--(int) { ptr = ptr->ilprev; } /* The iterator is simply a pointer. */ TransAp *ptr; }; }; typedef DList TransList; /* Set of states, list of states. */ typedef BstSet StateSet; typedef DList StateList; /* A element in a state dict. */ struct StateDictEl : public AvlTreeEl { StateDictEl(const StateSet &stateSet) : stateSet(stateSet) { } const StateSet &getKey() { return stateSet; } StateSet stateSet; StateAp *targState; }; /* Dictionary mapping a set of states to a target state. */ typedef AvlTree< StateDictEl, StateSet, CmpTable > StateDict; /* Data needed for a merge operation. */ struct MergeData { MergeData() : stfillHead(0), stfillTail(0) { } StateDict stateDict; StateAp *stfillHead; StateAp *stfillTail; void fillListAppend( StateAp *state ); }; struct TransEl { /* Constructors. */ TransEl() { } TransEl( Key lowKey, Key highKey ) : lowKey(lowKey), highKey(highKey) { } TransEl( Key lowKey, Key highKey, TransAp *value ) : lowKey(lowKey), highKey(highKey), value(value) { } Key lowKey, highKey; TransAp *value; }; struct CmpKey { static int compare( const Key key1, const Key key2 ) { if ( key1 < key2 ) return -1; else if ( key1 > key2 ) return 1; else return 0; } }; /* Vector based set of key items. */ typedef BstSet KeySet; struct MinPartition { MinPartition() : active(false) { } StateList list; bool active; MinPartition *prev, *next; }; /* Epsilon transition stored in a state. Specifies the target */ typedef Vector EpsilonTrans; /* List of states that are to be drawn into this. */ struct EptVectEl { EptVectEl( StateAp *targ, bool leaving ) : targ(targ), leaving(leaving) { } StateAp *targ; bool leaving; }; typedef Vector EptVect; /* Set of entry ids that go into this state. */ typedef BstSet EntryIdSet; /* Set of longest match items that may be active in a given state. */ typedef BstSet LmItemSet; /* A Conditions which is to be * transfered on pending out transitions. */ struct OutCond { OutCond( Action *action, bool sense ) : action(action), sense(sense) {} Action *action; bool sense; }; struct CmpOutCond { static int compare( const OutCond &outCond1, const OutCond &outCond2 ) { if ( outCond1.action < outCond2.action ) return -1; else if ( outCond1.action > outCond2.action ) return 1; else if ( outCond1.sense < outCond2.sense ) return -1; else if ( outCond1.sense > outCond2.sense ) return 1; return 0; } }; /* Set of conditions to be transfered to on pending out transitions. */ typedef SBstSet< OutCond, CmpOutCond > OutCondSet; typedef CmpSTable< OutCond, CmpOutCond > CmpOutCondSet; /* Conditions. */ typedef BstSet< Action*, CmpCondId > CondSet; typedef CmpTable< Action*, CmpCondId > CmpCondSet; struct CondSpace : public AvlTreeEl { CondSpace( const CondSet &condSet ) : condSet(condSet) {} const CondSet &getKey() { return condSet; } CondSet condSet; Key baseKey; long condSpaceId; }; typedef Vector CondSpaceVect; typedef AvlTree CondSpaceMap; struct StateCond { StateCond( Key lowKey, Key highKey ) : lowKey(lowKey), highKey(highKey) {} Key lowKey; Key highKey; CondSpace *condSpace; StateCond *prev, *next; }; typedef DList StateCondList; typedef Vector LongVect; struct Expansion { Expansion( Key lowKey, Key highKey ) : lowKey(lowKey), highKey(highKey), fromTrans(0), fromCondSpace(0), toCondSpace(0) {} ~Expansion() { if ( fromTrans != 0 ) delete fromTrans; } Key lowKey; Key highKey; TransAp *fromTrans; CondSpace *fromCondSpace; long fromVals; CondSpace *toCondSpace; LongVect toValsList; Expansion *prev, *next; }; typedef DList ExpansionList; struct Removal { Key lowKey; Key highKey; Removal *next; }; struct CondData { CondData() : lastCondKey(0) {} /* Condition info. */ Key lastCondKey; CondSpaceMap condSpaceMap; }; extern CondData *condData; struct FsmConstructFail { enum Reason { CondNoKeySpace }; FsmConstructFail( Reason reason ) : reason(reason) {} Reason reason; }; /* State class that implements actions and priorities. */ struct StateAp { StateAp(); StateAp(const StateAp &other); ~StateAp(); /* Is the state final? */ bool isFinState() { return stateBits & STB_ISFINAL; } /* Out transition list and the pointer for the default out trans. */ TransList outList; /* In transition Lists. */ TransInList inList; /* Set only during scanner construction when actions are added. NFA to DFA * code can ignore this. */ StateAp *eofTarget; /* Entry points into the state. */ EntryIdSet entryIds; /* Epsilon transitions. */ EpsilonTrans epsilonTrans; /* Condition info. */ StateCondList stateCondList; /* Number of in transitions from states other than ourselves. */ int foreignInTrans; /* Temporary data for various algorithms. */ union { /* When duplicating the fsm we need to map each * state to the new state representing it. */ StateAp *stateMap; /* When minimizing machines by partitioning, this maps to the group * the state is in. */ MinPartition *partition; /* When merging states (state machine operations) this next pointer is * used for the list of states that need to be filled in. */ StateAp *next; /* Identification for printing and stable minimization. */ int stateNum; } alg; /* Data used in epsilon operation, maybe fit into alg? */ StateAp *isolatedShadow; int owningGraph; /* A pointer to a dict element that contains the set of states this state * represents. This cannot go into alg, because alg.next is used during * the merging process. */ StateDictEl *stateDictEl; /* When drawing epsilon transitions, holds the list of states to merge * with. */ EptVect *eptVect; /* Bits controlling the behaviour of the state during collapsing to dfa. */ int stateBits; /* State list elements. */ StateAp *next, *prev; /* * Priority and Action data. */ /* Out priorities transfered to out transitions. */ PriorTable outPriorTable; /* The following two action tables are distinguished by the fact that when * toState actions are executed immediatly after transition actions of * incoming transitions and the current character will be the same as the * one available then. The fromState actions are executed immediately * before the transition actions of outgoing transitions and the current * character is same as the one available then. */ /* Actions to execute upon entering into a state. */ ActionTable toStateActionTable; /* Actions to execute when going from the state to the transition. */ ActionTable fromStateActionTable; /* Actions to add to any future transitions that leave via this state. */ ActionTable outActionTable; /* Conditions to add to any future transiions that leave via this sttate. */ OutCondSet outCondSet; /* Error action tables. */ ErrActionTable errActionTable; /* Actions to execute on eof. */ ActionTable eofActionTable; /* Set of longest match items that may be active in this state. */ LmItemSet lmItemSet; }; template struct NextTrans { Key lowKey, highKey; ListItem *trans; ListItem *next; void load() { if ( trans == 0 ) next = 0; else { next = trans->next; lowKey = trans->lowKey; highKey = trans->highKey; } } void set( ListItem *t ) { trans = t; load(); } void increment() { trans = next; load(); } }; /* Encodes the different states that are meaningful to the of the iterator. */ enum PairIterUserState { RangeInS1, RangeInS2, RangeOverlap, BreakS1, BreakS2 }; template struct PairIter { /* Encodes the different states that an fsm iterator can be in. */ enum IterState { Begin, ConsumeS1Range, ConsumeS2Range, OnlyInS1Range, OnlyInS2Range, S1SticksOut, S1SticksOutBreak, S2SticksOut, S2SticksOutBreak, S1DragsBehind, S1DragsBehindBreak, S2DragsBehind, S2DragsBehindBreak, ExactOverlap, End }; PairIter( ListItem1 *list1, ListItem2 *list2 ); /* Query iterator. */ bool lte() { return itState != End; } bool end() { return itState == End; } void operator++(int) { findNext(); } void operator++() { findNext(); } /* Iterator state. */ ListItem1 *list1; ListItem2 *list2; IterState itState; PairIterUserState userState; NextTrans s1Tel; NextTrans s2Tel; Key bottomLow, bottomHigh; ListItem1 *bottomTrans1; ListItem2 *bottomTrans2; private: void findNext(); }; /* Init the iterator by advancing to the first item. */ template PairIter::PairIter( ListItem1 *list1, ListItem2 *list2 ) : list1(list1), list2(list2), itState(Begin) { findNext(); } /* Return and re-entry for the co-routine iterators. This should ALWAYS be * used inside of a block. */ #define CO_RETURN(label) \ itState = label; \ return; \ entry##label: {} /* Return and re-entry for the co-routine iterators. This should ALWAYS be * used inside of a block. */ #define CO_RETURN2(label, uState) \ itState = label; \ userState = uState; \ return; \ entry##label: {} /* Advance to the next transition. When returns, trans points to the next * transition, unless there are no more, in which case end() returns true. */ template void PairIter::findNext() { /* Jump into the iterator routine base on the iterator state. */ switch ( itState ) { case Begin: goto entryBegin; case ConsumeS1Range: goto entryConsumeS1Range; case ConsumeS2Range: goto entryConsumeS2Range; case OnlyInS1Range: goto entryOnlyInS1Range; case OnlyInS2Range: goto entryOnlyInS2Range; case S1SticksOut: goto entryS1SticksOut; case S1SticksOutBreak: goto entryS1SticksOutBreak; case S2SticksOut: goto entryS2SticksOut; case S2SticksOutBreak: goto entryS2SticksOutBreak; case S1DragsBehind: goto entryS1DragsBehind; case S1DragsBehindBreak: goto entryS1DragsBehindBreak; case S2DragsBehind: goto entryS2DragsBehind; case S2DragsBehindBreak: goto entryS2DragsBehindBreak; case ExactOverlap: goto entryExactOverlap; case End: goto entryEnd; } entryBegin: /* Set up the next structs at the head of the transition lists. */ s1Tel.set( list1 ); s2Tel.set( list2 ); /* Concurrently scan both out ranges. */ while ( true ) { if ( s1Tel.trans == 0 ) { /* We are at the end of state1's ranges. Process the rest of * state2's ranges. */ while ( s2Tel.trans != 0 ) { /* Range is only in s2. */ CO_RETURN2( ConsumeS2Range, RangeInS2 ); s2Tel.increment(); } break; } else if ( s2Tel.trans == 0 ) { /* We are at the end of state2's ranges. Process the rest of * state1's ranges. */ while ( s1Tel.trans != 0 ) { /* Range is only in s1. */ CO_RETURN2( ConsumeS1Range, RangeInS1 ); s1Tel.increment(); } break; } /* Both state1's and state2's transition elements are good. * The signiture of no overlap is a back key being in front of a * front key. */ else if ( s1Tel.highKey < s2Tel.lowKey ) { /* A range exists in state1 that does not overlap with state2. */ CO_RETURN2( OnlyInS1Range, RangeInS1 ); s1Tel.increment(); } else if ( s2Tel.highKey < s1Tel.lowKey ) { /* A range exists in state2 that does not overlap with state1. */ CO_RETURN2( OnlyInS2Range, RangeInS2 ); s2Tel.increment(); } /* There is overlap, must mix the ranges in some way. */ else if ( s1Tel.lowKey < s2Tel.lowKey ) { /* Range from state1 sticks out front. Must break it into * non-overlaping and overlaping segments. */ bottomLow = s2Tel.lowKey; bottomHigh = s1Tel.highKey; s1Tel.highKey = s2Tel.lowKey; s1Tel.highKey.decrement(); bottomTrans1 = s1Tel.trans; /* Notify the caller that we are breaking s1. This gives them a * chance to duplicate s1Tel[0,1].value. */ CO_RETURN2( S1SticksOutBreak, BreakS1 ); /* Broken off range is only in s1. */ CO_RETURN2( S1SticksOut, RangeInS1 ); /* Advance over the part sticking out front. */ s1Tel.lowKey = bottomLow; s1Tel.highKey = bottomHigh; s1Tel.trans = bottomTrans1; } else if ( s2Tel.lowKey < s1Tel.lowKey ) { /* Range from state2 sticks out front. Must break it into * non-overlaping and overlaping segments. */ bottomLow = s1Tel.lowKey; bottomHigh = s2Tel.highKey; s2Tel.highKey = s1Tel.lowKey; s2Tel.highKey.decrement(); bottomTrans2 = s2Tel.trans; /* Notify the caller that we are breaking s2. This gives them a * chance to duplicate s2Tel[0,1].value. */ CO_RETURN2( S2SticksOutBreak, BreakS2 ); /* Broken off range is only in s2. */ CO_RETURN2( S2SticksOut, RangeInS2 ); /* Advance over the part sticking out front. */ s2Tel.lowKey = bottomLow; s2Tel.highKey = bottomHigh; s2Tel.trans = bottomTrans2; } /* Low ends are even. Are the high ends even? */ else if ( s1Tel.highKey < s2Tel.highKey ) { /* Range from state2 goes longer than the range from state1. We * must break the range from state2 into an evenly overlaping * segment. */ bottomLow = s1Tel.highKey; bottomLow.increment(); bottomHigh = s2Tel.highKey; s2Tel.highKey = s1Tel.highKey; bottomTrans2 = s2Tel.trans; /* Notify the caller that we are breaking s2. This gives them a * chance to duplicate s2Tel[0,1].value. */ CO_RETURN2( S2DragsBehindBreak, BreakS2 ); /* Breaking s2 produces exact overlap. */ CO_RETURN2( S2DragsBehind, RangeOverlap ); /* Advance over the front we just broke off of range 2. */ s2Tel.lowKey = bottomLow; s2Tel.highKey = bottomHigh; s2Tel.trans = bottomTrans2; /* Advance over the entire s1Tel. We have consumed it. */ s1Tel.increment(); } else if ( s2Tel.highKey < s1Tel.highKey ) { /* Range from state1 goes longer than the range from state2. We * must break the range from state1 into an evenly overlaping * segment. */ bottomLow = s2Tel.highKey; bottomLow.increment(); bottomHigh = s1Tel.highKey; s1Tel.highKey = s2Tel.highKey; bottomTrans1 = s1Tel.trans; /* Notify the caller that we are breaking s1. This gives them a * chance to duplicate s2Tel[0,1].value. */ CO_RETURN2( S1DragsBehindBreak, BreakS1 ); /* Breaking s1 produces exact overlap. */ CO_RETURN2( S1DragsBehind, RangeOverlap ); /* Advance over the front we just broke off of range 1. */ s1Tel.lowKey = bottomLow; s1Tel.highKey = bottomHigh; s1Tel.trans = bottomTrans1; /* Advance over the entire s2Tel. We have consumed it. */ s2Tel.increment(); } else { /* There is an exact overlap. */ CO_RETURN2( ExactOverlap, RangeOverlap ); s1Tel.increment(); s2Tel.increment(); } } /* Done, go into end state. */ CO_RETURN( End ); } /* Compare lists of epsilon transitions. Entries are name ids of targets. */ typedef CmpTable< int, CmpOrd > CmpEpsilonTrans; /* Compare class for the Approximate minimization. */ class ApproxCompare { public: ApproxCompare() { } int compare( const StateAp *pState1, const StateAp *pState2 ); }; /* Compare class for the initial partitioning of a partition minimization. */ class InitPartitionCompare { public: InitPartitionCompare() { } int compare( const StateAp *pState1, const StateAp *pState2 ); }; /* Compare class for the regular partitioning of a partition minimization. */ class PartitionCompare { public: PartitionCompare() { } int compare( const StateAp *pState1, const StateAp *pState2 ); }; /* Compare class for a minimization that marks pairs. Provides the shouldMark * routine. */ class MarkCompare { public: MarkCompare() { } bool shouldMark( MarkIndex &markIndex, const StateAp *pState1, const StateAp *pState2 ); }; /* List of partitions. */ typedef DList< MinPartition > PartitionList; /* List of transtions out of a state. */ typedef Vector TransListVect; /* Entry point map used for keeping track of entry points in a machine. */ typedef BstSet< int > EntryIdSet; typedef BstMapEl< int, StateAp* > EntryMapEl; typedef BstMap< int, StateAp* > EntryMap; typedef Vector EntryMapBase; /* Graph class that implements actions and priorities. */ struct FsmAp { /* Constructors/Destructors. */ FsmAp( ); FsmAp( const FsmAp &graph ); ~FsmAp(); /* The list of states. */ StateList stateList; StateList misfitList; /* The map of entry points. */ EntryMap entryPoints; /* The start state. */ StateAp *startState; /* Error state, possibly created only when the final machine has been * created and the XML machine is about to be written. No transitions * point to this state. */ StateAp *errState; /* The set of final states. */ StateSet finStateSet; /* Misfit Accounting. Are misfits put on a separate list. */ bool misfitAccounting; /* * Transition actions and priorities. */ /* Set priorities on transtions. */ void startFsmPrior( int ordering, PriorDesc *prior ); void allTransPrior( int ordering, PriorDesc *prior ); void finishFsmPrior( int ordering, PriorDesc *prior ); void leaveFsmPrior( int ordering, PriorDesc *prior ); /* Action setting support. */ void transferOutActions( StateAp *state ); void transferErrorActions( StateAp *state, int transferPoint ); void setErrorActions( StateAp *state, const ActionTable &other ); void setErrorAction( StateAp *state, int ordering, Action *action ); /* Fill all spaces in a transition list with an error transition. */ void fillGaps( StateAp *state ); /* Similar to setErrorAction, instead gives a state to go to on error. */ void setErrorTarget( StateAp *state, StateAp *target, int *orderings, Action **actions, int nActs ); /* Set actions to execute. */ void startFsmAction( int ordering, Action *action ); void allTransAction( int ordering, Action *action ); void finishFsmAction( int ordering, Action *action ); void leaveFsmAction( int ordering, Action *action ); void longMatchAction( int ordering, LongestMatchPart *lmPart ); /* Set conditions. */ CondSpace *addCondSpace( const CondSet &condSet ); void findEmbedExpansions( ExpansionList &expansionList, StateAp *destState, Action *condAction, bool sense ); void embedCondition( MergeData &md, StateAp *state, Action *condAction, bool sense ); void embedCondition( StateAp *state, Action *condAction, bool sense ); void startFsmCondition( Action *condAction, bool sense ); void allTransCondition( Action *condAction, bool sense ); void leaveFsmCondition( Action *condAction, bool sense ); /* Set error actions to execute. */ void startErrorAction( int ordering, Action *action, int transferPoint ); void allErrorAction( int ordering, Action *action, int transferPoint ); void finalErrorAction( int ordering, Action *action, int transferPoint ); void notStartErrorAction( int ordering, Action *action, int transferPoint ); void notFinalErrorAction( int ordering, Action *action, int transferPoint ); void middleErrorAction( int ordering, Action *action, int transferPoint ); /* Set EOF actions. */ void startEOFAction( int ordering, Action *action ); void allEOFAction( int ordering, Action *action ); void finalEOFAction( int ordering, Action *action ); void notStartEOFAction( int ordering, Action *action ); void notFinalEOFAction( int ordering, Action *action ); void middleEOFAction( int ordering, Action *action ); /* Set To State actions. */ void startToStateAction( int ordering, Action *action ); void allToStateAction( int ordering, Action *action ); void finalToStateAction( int ordering, Action *action ); void notStartToStateAction( int ordering, Action *action ); void notFinalToStateAction( int ordering, Action *action ); void middleToStateAction( int ordering, Action *action ); /* Set From State actions. */ void startFromStateAction( int ordering, Action *action ); void allFromStateAction( int ordering, Action *action ); void finalFromStateAction( int ordering, Action *action ); void notStartFromStateAction( int ordering, Action *action ); void notFinalFromStateAction( int ordering, Action *action ); void middleFromStateAction( int ordering, Action *action ); /* Shift the action ordering of the start transitions to start at * fromOrder and increase in units of 1. Useful before kleene star * operation. */ int shiftStartActionOrder( int fromOrder ); /* Clear all priorities from the fsm to so they won't affcet minimization * of the final fsm. */ void clearAllPriorities(); /* Zero out all the function keys. */ void nullActionKeys(); /* Walk the list of states and verify state properties. */ void verifyStates(); /* Misfit Accounting. Are misfits put on a separate list. */ void setMisfitAccounting( bool val ) { misfitAccounting = val; } /* Set and Unset a state as final. */ void setFinState( StateAp *state ); void unsetFinState( StateAp *state ); void setStartState( StateAp *state ); void unsetStartState( ); /* Set and unset a state as an entry point. */ void setEntry( int id, StateAp *state ); void changeEntry( int id, StateAp *to, StateAp *from ); void unsetEntry( int id, StateAp *state ); void unsetEntry( int id ); void unsetAllEntryPoints(); /* Epsilon transitions. */ void epsilonTrans( int id ); void shadowReadWriteStates( MergeData &md ); /* * Basic attaching and detaching. */ /* Common to attaching/detaching list and default. */ void attachToInList( StateAp *from, StateAp *to, TransAp *&head, TransAp *trans ); void detachFromInList( StateAp *from, StateAp *to, TransAp *&head, TransAp *trans ); /* Attach with a new transition. */ TransAp *attachNewTrans( StateAp *from, StateAp *to, Key onChar1, Key onChar2 ); /* Attach with an existing transition that already in an out list. */ void attachTrans( StateAp *from, StateAp *to, TransAp *trans ); /* Redirect a transition away from error and towards some state. */ void redirectErrorTrans( StateAp *from, StateAp *to, TransAp *trans ); /* Detach a transition from a target state. */ void detachTrans( StateAp *from, StateAp *to, TransAp *trans ); /* Detach a state from the graph. */ void detachState( StateAp *state ); /* * NFA to DFA conversion routines. */ /* Duplicate a transition that will dropin to a free spot. */ TransAp *dupTrans( StateAp *from, TransAp *srcTrans ); /* In crossing, two transitions both go to real states. */ TransAp *fsmAttachStates( MergeData &md, StateAp *from, TransAp *destTrans, TransAp *srcTrans ); /* Two transitions are to be crossed, handle the possibility of either * going to the error state. */ TransAp *mergeTrans( MergeData &md, StateAp *from, TransAp *destTrans, TransAp *srcTrans ); /* Compare deterimne relative priorities of two transition tables. */ int comparePrior( const PriorTable &priorTable1, const PriorTable &priorTable2 ); /* Cross a src transition with one that is already occupying a spot. */ TransAp *crossTransitions( MergeData &md, StateAp *from, TransAp *destTrans, TransAp *srcTrans ); void outTransCopy( MergeData &md, StateAp *dest, TransAp *srcList ); void doRemove( MergeData &md, StateAp *destState, ExpansionList &expList1 ); void doExpand( MergeData &md, StateAp *destState, ExpansionList &expList1 ); void findCondExpInTrans( ExpansionList &expansionList, StateAp *state, Key lowKey, Key highKey, CondSpace *fromCondSpace, CondSpace *toCondSpace, long destVals, LongVect &toValsList ); void findTransExpansions( ExpansionList &expansionList, StateAp *destState, StateAp *srcState ); void findCondExpansions( ExpansionList &expansionList, StateAp *destState, StateAp *srcState ); void mergeStateConds( StateAp *destState, StateAp *srcState ); /* Merge a set of states into newState. */ void mergeStates( MergeData &md, StateAp *destState, StateAp **srcStates, int numSrc ); void mergeStatesLeaving( MergeData &md, StateAp *destState, StateAp *srcState ); void mergeStates( MergeData &md, StateAp *destState, StateAp *srcState ); /* Make all states that are combinations of other states and that * have not yet had their out transitions filled in. This will * empty out stateDict and stFil. */ void fillInStates( MergeData &md ); /* * Transition Comparison. */ /* Compare transition data. Either of the pointers may be null. */ static inline int compareDataPtr( TransAp *trans1, TransAp *trans2 ); /* Compare target state and transition data. Either pointer may be null. */ static inline int compareFullPtr( TransAp *trans1, TransAp *trans2 ); /* Compare target partitions. Either pointer may be null. */ static inline int comparePartPtr( TransAp *trans1, TransAp *trans2 ); /* Check marked status of target states. Either pointer may be null. */ static inline bool shouldMarkPtr( MarkIndex &markIndex, TransAp *trans1, TransAp *trans2 ); /* * Callbacks. */ /* Compare priority and function table of transitions. */ static int compareTransData( TransAp *trans1, TransAp *trans2 ); /* Add in the properties of srcTrans into this. */ void addInTrans( TransAp *destTrans, TransAp *srcTrans ); /* Compare states on data stored in the states. */ static int compareStateData( const StateAp *state1, const StateAp *state2 ); /* Out transition data. */ void clearOutData( StateAp *state ); bool hasOutData( StateAp *state ); void transferOutData( StateAp *destState, StateAp *srcState ); /* * Allocation. */ /* New up a state and add it to the graph. */ StateAp *addState(); /* * Building basic machines */ void concatFsm( Key c ); void concatFsm( Key *str, int len ); void concatFsmCI( Key *str, int len ); void orFsm( Key *set, int len ); void rangeFsm( Key low, Key high ); void rangeStarFsm( Key low, Key high ); void emptyFsm( ); void lambdaFsm( ); /* * Fsm operators. */ void starOp( ); void repeatOp( int times ); void optionalRepeatOp( int times ); void concatOp( FsmAp *other ); void unionOp( FsmAp *other ); void intersectOp( FsmAp *other ); void subtractOp( FsmAp *other ); void epsilonOp(); void joinOp( int startId, int finalId, FsmAp **others, int numOthers ); void globOp( FsmAp **others, int numOthers ); void deterministicEntry(); /* * Operator workers */ /* Determine if there are any entry points into a start state other than * the start state. */ bool isStartStateIsolated(); /* Make a new start state that has no entry points. Will not change the * identity of the fsm. */ void isolateStartState(); /* Workers for resolving epsilon transitions. */ bool inEptVect( EptVect *eptVect, StateAp *targ ); void epsilonFillEptVectFrom( StateAp *root, StateAp *from, bool parentLeaving ); void resolveEpsilonTrans( MergeData &md ); /* Workers for concatenation and union. */ void doConcat( FsmAp *other, StateSet *fromStates, bool optional ); void doOr( FsmAp *other ); /* * Final states */ /* Unset any final states that are no longer to be final * due to final bits. */ void unsetIncompleteFinals(); void unsetKilledFinals(); /* Bring in other's entry points. Assumes others states are going to be * copied into this machine. */ void copyInEntryPoints( FsmAp *other ); /* Ordering states. */ void depthFirstOrdering( StateAp *state ); void depthFirstOrdering(); void sortStatesByFinal(); /* Set sqequential state numbers starting at 0. */ void setStateNumbers( int base ); /* Unset all final states. */ void unsetAllFinStates(); /* Set the bits of final states and clear the bits of non final states. */ void setFinBits( int finStateBits ); /* * Self-consistency checks. */ /* Run a sanity check on the machine. */ void verifyIntegrity(); /* Verify that there are no unreachable states, or dead end states. */ void verifyReachability(); void verifyNoDeadEndStates(); /* * Path pruning */ /* Mark all states reachable from state. */ void markReachableFromHereReverse( StateAp *state ); /* Mark all states reachable from state. */ void markReachableFromHere( StateAp *state ); void markReachableFromHereStopFinal( StateAp *state ); /* Removes states that cannot be reached by any path in the fsm and are * thus wasted silicon. */ void removeDeadEndStates(); /* Removes states that cannot be reached by any path in the fsm and are * thus wasted silicon. */ void removeUnreachableStates(); /* Remove error actions from states on which the error transition will * never be taken. */ bool outListCovers( StateAp *state ); bool anyErrorRange( StateAp *state ); /* Remove states that are on the misfit list. */ void removeMisfits(); /* * FSM Minimization */ /* Minimization by partitioning. */ void minimizePartition1(); void minimizePartition2(); /* Minimize the final state Machine. The result is the minimal fsm. Slow * but stable, correct minimization. Uses n^2 space (lookout) and average * n^2 time. Worst case n^3 time, but a that is a very rare case. */ void minimizeStable(); /* Minimize the final state machine. Does not find the minimal fsm, but a * pretty good approximation. Does not use any extra space. Average n^2 * time. Worst case n^3 time, but a that is a very rare case. */ void minimizeApproximate(); /* This is the worker for the minimize approximate solution. It merges * states that have identical out transitions. */ bool minimizeRound( ); /* Given an intial partioning of states, split partitions that have out trans * to differing partitions. */ int partitionRound( StateAp **statePtrs, MinPartition *parts, int numParts ); /* Split partitions that have a transition to a previously split partition, until * there are no more partitions to split. */ int splitCandidates( StateAp **statePtrs, MinPartition *parts, int numParts ); /* Fuse together states in the same partition. */ void fusePartitions( MinPartition *parts, int numParts ); /* Mark pairs where out final stateness differs, out trans data differs, * trans pairs go to a marked pair or trans data differs. Should get * alot of pairs. */ void initialMarkRound( MarkIndex &markIndex ); /* One marking round on all state pairs. Considers if trans pairs go * to a marked state only. Returns whether or not a pair was marked. */ bool markRound( MarkIndex &markIndex ); /* Move the in trans into src into dest. */ void inTransMove(StateAp *dest, StateAp *src); /* Make state src and dest the same state. */ void fuseEquivStates(StateAp *dest, StateAp *src); /* Find any states that didn't get marked by the marking algorithm and * merge them into the primary states of their equivalence class. */ void fuseUnmarkedPairs( MarkIndex &markIndex ); /* Merge neighboring transitions go to the same state and have the same * transitions data. */ void compressTransitions(); /* Returns true if there is a transtion (either explicit or by a gap) to * the error state. */ bool checkErrTrans( StateAp *state, TransAp *trans ); bool checkErrTransFinish( StateAp *state ); bool hasErrorTrans(); /* Check if a machine defines a single character. This is useful in * validating ranges and machines to export. */ bool checkSingleCharMachine( ); }; #endif ragel-6.10/ragel/csflat.h0000664000175000017500000000560113065111230012166 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CSFLAT_H #define _CSFLAT_H #include #include "cscodegen.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; /* * CSharpFlatCodeGen */ class CSharpFlatCodeGen : virtual public CSharpFsmCodeGen, public CSharpCodeGen { public: CSharpFlatCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpCodeGen(out) {} virtual ~CSharpFlatCodeGen() { } protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &FLAT_INDEX_OFFSET(); std::ostream &KEY_SPANS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); void LOCATE_TRANS(); std::ostream &COND_INDEX_OFFSET(); void COND_TRANSLATE(); std::ostream &CONDS(); std::ostream &COND_KEYS(); std::ostream &COND_KEY_SPANS(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); void initVarTypes(); string slenType, transType, indsType, condsType; }; #endif ragel-6.10/ragel/cdipgoto.h0000664000175000017500000000571013065111230012523 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDIPGOTO_H #define _CDIPGOTO_H #include #include "cdgoto.h" /* Forwards. */ struct CodeGenData; /* * class FGotoCodeGen */ class IpGotoCodeGen : public GotoCodeGen { public: IpGotoCodeGen( ostream &out ) : FsmCodeGen(out), GotoCodeGen(out) {} std::ostream &EXIT_STATES(); std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); std::ostream &FINISH_CASES(); std::ostream &AGAIN_CASES(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void RET( ostream &ret, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void BREAK( ostream &ret, int targState, bool csForced ); virtual void writeData(); virtual void writeExec(); protected: bool useAgainLabel(); void EOF_CHECK( ostream &ret, int gotoDest ); /* Called from GotoCodeGen::STATE_GOTOS just before writing the gotos for * each state. */ bool IN_TRANS_ACTIONS( RedStateAp *state ); void GOTO_HEADER( RedStateAp *state ); void STATE_GOTO_ERROR(); /* Set up labelNeeded flag for each state. */ void setLabelsNeeded( GenInlineList *inlineList ); void setLabelsNeeded(); }; /* * class CIpGotoCodeGen */ struct CIpGotoCodeGen : public IpGotoCodeGen, public CCodeGen { CIpGotoCodeGen( ostream &out ) : FsmCodeGen(out), IpGotoCodeGen(out), CCodeGen(out) {} }; /* * class DIpGotoCodeGen */ struct DIpGotoCodeGen : public IpGotoCodeGen, public DCodeGen { DIpGotoCodeGen( ostream &out ) : FsmCodeGen(out), IpGotoCodeGen(out), DCodeGen(out) {} }; /* * class D2IpGotoCodeGen */ struct D2IpGotoCodeGen : public IpGotoCodeGen, public D2CodeGen { D2IpGotoCodeGen( ostream &out ) : FsmCodeGen(out), IpGotoCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/version.h0000664000175000017500000000006413065122657012414 00000000000000#define VERSION "6.10" #define PUBDATE "March 2017" ragel-6.10/ragel/csftable.h0000664000175000017500000000325513065111230012500 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CSFTABLE_H #define _CSFTABLE_H #include #include "cstable.h" /* Forwards. */ struct CodeGenData; /* * CSharpFTabCodeGen */ class CSharpFTabCodeGen : public CSharpTabCodeGen { public: CSharpFTabCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpTabCodeGen(out) {} private: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); virtual void calcIndexSize(); }; #endif ragel-6.10/ragel/fsmbase.cpp0000664000175000017500000004213413065111230012667 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "fsmgraph.h" /* Simple singly linked list append routine for the fill list. The new state * goes to the end of the list. */ void MergeData::fillListAppend( StateAp *state ) { state->alg.next = 0; if ( stfillHead == 0 ) { /* List is empty, state becomes head and tail. */ stfillHead = state; stfillTail = state; } else { /* List is not empty, state goes after last element. */ stfillTail->alg.next = state; stfillTail = state; } } /* Graph constructor. */ FsmAp::FsmAp() : /* No start state. */ startState(0), errState(0), /* Misfit accounting is a switch, turned on only at specific times. It * controls what happens when states have no way in from the outside * world.. */ misfitAccounting(false) { } /* Copy all graph data including transitions. */ FsmAp::FsmAp( const FsmAp &graph ) : /* Lists start empty. Will be filled by copy. */ stateList(), misfitList(), /* Copy in the entry points, * pointers will be resolved later. */ entryPoints(graph.entryPoints), startState(graph.startState), errState(0), /* Will be filled by copy. */ finStateSet(), /* Misfit accounting is only on during merging. */ misfitAccounting(false) { /* Create the states and record their map in the original state. */ StateList::Iter origState = graph.stateList; for ( ; origState.lte(); origState++ ) { /* Make the new state. */ StateAp *newState = new StateAp( *origState ); /* Add the state to the list. */ stateList.append( newState ); /* Set the mapsTo item of the old state. */ origState->alg.stateMap = newState; } /* Derefernce all the state maps. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { /* The points to the original in the src machine. The taget's duplicate * is in the statemap. */ StateAp *toState = trans->toState != 0 ? trans->toState->alg.stateMap : 0; /* Attach The transition to the duplicate. */ trans->toState = 0; attachTrans( state, toState, trans ); } /* Fix the eofTarg, if set. */ if ( state->eofTarget != 0 ) state->eofTarget = state->eofTarget->alg.stateMap; } /* Fix the state pointers in the entry points array. */ EntryMapEl *eel = entryPoints.data; for ( int e = 0; e < entryPoints.length(); e++, eel++ ) { /* Get the duplicate of the state. */ eel->value = eel->value->alg.stateMap; /* Foreign in transitions must be built up when duping machines so * increment it here. */ eel->value->foreignInTrans += 1; } /* Fix the start state pointer and the new start state's count of in * transiions. */ startState = startState->alg.stateMap; startState->foreignInTrans += 1; /* Build the final state set. */ StateSet::Iter st = graph.finStateSet; for ( ; st.lte(); st++ ) finStateSet.insert((*st)->alg.stateMap); } /* Deletes all transition data then deletes each state. */ FsmAp::~FsmAp() { /* Delete all the transitions. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Iterate the out transitions, deleting them. */ state->outList.empty(); } /* Delete all the states. */ stateList.empty(); } /* Set a state final. The state has its isFinState set to true and the state * is added to the finStateSet. */ void FsmAp::setFinState( StateAp *state ) { /* Is it already a fin state. */ if ( state->stateBits & STB_ISFINAL ) return; state->stateBits |= STB_ISFINAL; finStateSet.insert( state ); } /* Set a state non-final. The has its isFinState flag set false and the state * is removed from the final state set. */ void FsmAp::unsetFinState( StateAp *state ) { /* Is it already a non-final state? */ if ( ! (state->stateBits & STB_ISFINAL) ) return; /* When a state looses its final state status it must relinquish all the * properties that are allowed only for final states. */ clearOutData( state ); state->stateBits &= ~ STB_ISFINAL; finStateSet.remove( state ); } /* Set and unset a state as the start state. */ void FsmAp::setStartState( StateAp *state ) { /* Sould change from unset to set. */ assert( startState == 0 ); startState = state; if ( misfitAccounting ) { /* If the number of foreign in transitions is about to go up to 1 then * take it off the misfit list and put it on the head list. */ if ( state->foreignInTrans == 0 ) stateList.append( misfitList.detach( state ) ); } /* Up the foreign in transitions to the state. */ state->foreignInTrans += 1; } void FsmAp::unsetStartState() { /* Should change from set to unset. */ assert( startState != 0 ); /* Decrement the entry's count of foreign entries. */ startState->foreignInTrans -= 1; if ( misfitAccounting ) { /* If the number of foreign in transitions just went down to 0 then take * it off the main list and put it on the misfit list. */ if ( startState->foreignInTrans == 0 ) misfitList.append( stateList.detach( startState ) ); } startState = 0; } /* Associate an id with a state. Makes the state a named entry point. Has no * effect if the entry point is already mapped to the state. */ void FsmAp::setEntry( int id, StateAp *state ) { /* Insert the id into the state. If the state is already labelled with id, * nothing to do. */ if ( state->entryIds.insert( id ) ) { /* Insert the entry and assert that it succeeds. */ entryPoints.insertMulti( id, state ); if ( misfitAccounting ) { /* If the number of foreign in transitions is about to go up to 1 then * take it off the misfit list and put it on the head list. */ if ( state->foreignInTrans == 0 ) stateList.append( misfitList.detach( state ) ); } /* Up the foreign in transitions to the state. */ state->foreignInTrans += 1; } } /* Remove the association of an id with a state. The state looses it's entry * point status. Assumes that the id is indeed mapped to state. */ void FsmAp::unsetEntry( int id, StateAp *state ) { /* Find the entry point in on id. */ EntryMapEl *enLow = 0, *enHigh = 0; entryPoints.findMulti( id, enLow, enHigh ); while ( enLow->value != state ) enLow += 1; /* Remove the record from the map. */ entryPoints.remove( enLow ); /* Remove the state's sense of the link. */ state->entryIds.remove( id ); state->foreignInTrans -= 1; if ( misfitAccounting ) { /* If the number of foreign in transitions just went down to 0 then take * it off the main list and put it on the misfit list. */ if ( state->foreignInTrans == 0 ) misfitList.append( stateList.detach( state ) ); } } /* Remove all association of an id with states. Assumes that the id is indeed * mapped to a state. */ void FsmAp::unsetEntry( int id ) { /* Find the entry point in on id. */ EntryMapEl *enLow = 0, *enHigh = 0; entryPoints.findMulti( id, enLow, enHigh ); for ( EntryMapEl *mel = enLow; mel <= enHigh; mel++ ) { /* Remove the state's sense of the link. */ mel->value->entryIds.remove( id ); mel->value->foreignInTrans -= 1; if ( misfitAccounting ) { /* If the number of foreign in transitions just went down to 0 * then take it off the main list and put it on the misfit list. */ if ( mel->value->foreignInTrans == 0 ) misfitList.append( stateList.detach( mel->value ) ); } } /* Remove the records from the entry points map. */ entryPoints.removeMulti( enLow, enHigh ); } void FsmAp::changeEntry( int id, StateAp *to, StateAp *from ) { /* Find the entry in the entry map. */ EntryMapEl *enLow = 0, *enHigh = 0; entryPoints.findMulti( id, enLow, enHigh ); while ( enLow->value != from ) enLow += 1; /* Change it to the new target. */ enLow->value = to; /* Remove from's sense of the link. */ from->entryIds.remove( id ); from->foreignInTrans -= 1; if ( misfitAccounting ) { /* If the number of foreign in transitions just went down to 0 then take * it off the main list and put it on the misfit list. */ if ( from->foreignInTrans == 0 ) misfitList.append( stateList.detach( from ) ); } /* Add to's sense of the link. */ if ( to->entryIds.insert( id ) != 0 ) { if ( misfitAccounting ) { /* If the number of foreign in transitions is about to go up to 1 then * take it off the misfit list and put it on the head list. */ if ( to->foreignInTrans == 0 ) stateList.append( misfitList.detach( to ) ); } /* Up the foreign in transitions to the state. */ to->foreignInTrans += 1; } } /* Clear all entry points from a machine. */ void FsmAp::unsetAllEntryPoints() { for ( EntryMap::Iter en = entryPoints; en.lte(); en++ ) { /* Kill all the state's entry points at once. */ if ( en->value->entryIds.length() > 0 ) { en->value->foreignInTrans -= en->value->entryIds.length(); if ( misfitAccounting ) { /* If the number of foreign in transitions just went down to 0 * then take it off the main list and put it on the misfit * list. */ if ( en->value->foreignInTrans == 0 ) misfitList.append( stateList.detach( en->value ) ); } /* Clear the set of ids out all at once. */ en->value->entryIds.empty(); } } /* Now clear out the entry map all at once. */ entryPoints.empty(); } /* Assigning an epsilon transition into final states. */ void FsmAp::epsilonTrans( int id ) { for ( StateSet::Iter fs = finStateSet; fs.lte(); fs++ ) (*fs)->epsilonTrans.append( id ); } /* Mark all states reachable from state. Traverses transitions forward. Used * for removing states that have no path into them. */ void FsmAp::markReachableFromHere( StateAp *state ) { /* Base case: return; */ if ( state->stateBits & STB_ISMARKED ) return; /* Set this state as processed. We are going to visit all states that this * state has a transition to. */ state->stateBits |= STB_ISMARKED; /* Recurse on all out transitions. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { if ( trans->toState != 0 ) markReachableFromHere( trans->toState ); } } void FsmAp::markReachableFromHereStopFinal( StateAp *state ) { /* Base case: return; */ if ( state->stateBits & STB_ISMARKED ) return; /* Set this state as processed. We are going to visit all states that this * state has a transition to. */ state->stateBits |= STB_ISMARKED; /* Recurse on all out transitions. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { StateAp *toState = trans->toState; if ( toState != 0 && !toState->isFinState() ) markReachableFromHereStopFinal( toState ); } } /* Mark all states reachable from state. Traverse transitions backwards. Used * for removing dead end paths in graphs. */ void FsmAp::markReachableFromHereReverse( StateAp *state ) { /* Base case: return; */ if ( state->stateBits & STB_ISMARKED ) return; /* Set this state as processed. We are going to visit all states with * transitions into this state. */ state->stateBits |= STB_ISMARKED; /* Recurse on all items in transitions. */ for ( TransInList::Iter trans = state->inList; trans.lte(); trans++ ) markReachableFromHereReverse( trans->fromState ); } /* Determine if there are any entry points into a start state other than the * start state. Setting starting transitions requires that the start state be * isolated. In most cases a start state will already be isolated. */ bool FsmAp::isStartStateIsolated() { /* If there are any in transitions then the state is not isolated. */ if ( startState->inList.head != 0 ) return false; /* If there are any entry points then isolated. */ if ( startState->entryIds.length() > 0 ) return false; return true; } /* Bring in other's entry points. Assumes others states are going to be * copied into this machine. */ void FsmAp::copyInEntryPoints( FsmAp *other ) { /* Use insert multi because names are not unique. */ for ( EntryMap::Iter en = other->entryPoints; en.lte(); en++ ) entryPoints.insertMulti( en->key, en->value ); } void FsmAp::unsetAllFinStates() { for ( StateSet::Iter st = finStateSet; st.lte(); st++ ) (*st)->stateBits &= ~ STB_ISFINAL; finStateSet.empty(); } void FsmAp::setFinBits( int finStateBits ) { for ( int s = 0; s < finStateSet.length(); s++ ) finStateSet.data[s]->stateBits |= finStateBits; } /* Tests the integrity of the transition lists and the fromStates. */ void FsmAp::verifyIntegrity() { for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Walk the out transitions and assert fromState is correct. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) assert( trans->fromState == state ); /* Walk the inlist and assert toState is correct. */ for ( TransInList::Iter trans = state->inList; trans.lte(); trans++ ) assert( trans->toState == state ); } } void FsmAp::verifyReachability() { /* Mark all the states that can be reached * through the set of entry points. */ markReachableFromHere( startState ); for ( EntryMap::Iter en = entryPoints; en.lte(); en++ ) markReachableFromHere( en->value ); /* Check that everything got marked. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) { /* Assert it got marked and then clear the mark. */ assert( st->stateBits & STB_ISMARKED ); st->stateBits &= ~ STB_ISMARKED; } } void FsmAp::verifyNoDeadEndStates() { /* Mark all states that have paths to the final states. */ for ( StateSet::Iter pst = finStateSet; pst.lte(); pst++ ) markReachableFromHereReverse( *pst ); /* Start state gets honorary marking. Must be done AFTER recursive call. */ startState->stateBits |= STB_ISMARKED; /* Make sure everything got marked. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) { /* Assert the state got marked and unmark it. */ assert( st->stateBits & STB_ISMARKED ); st->stateBits &= ~ STB_ISMARKED; } } void FsmAp::depthFirstOrdering( StateAp *state ) { /* Nothing to do if the state is already on the list. */ if ( state->stateBits & STB_ONLIST ) return; /* Doing depth first, put state on the list. */ state->stateBits |= STB_ONLIST; stateList.append( state ); /* Recurse on everything ranges. */ for ( TransList::Iter tel = state->outList; tel.lte(); tel++ ) { if ( tel->toState != 0 ) depthFirstOrdering( tel->toState ); } } /* Ordering states by transition connections. */ void FsmAp::depthFirstOrdering() { /* Init on state list flags. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) st->stateBits &= ~STB_ONLIST; /* Clear out the state list, we will rebuild it. */ int stateListLen = stateList.length(); stateList.abandon(); /* Add back to the state list from the start state and all other entry * points. */ if ( errState != 0 ) depthFirstOrdering( errState ); depthFirstOrdering( startState ); for ( EntryMap::Iter en = entryPoints; en.lte(); en++ ) depthFirstOrdering( en->value ); /* Make sure we put everything back on. */ assert( stateListLen == stateList.length() ); } /* Stable sort the states by final state status. */ void FsmAp::sortStatesByFinal() { /* Move forward through the list and throw final states onto the end. */ StateAp *state = 0; StateAp *next = stateList.head; StateAp *last = stateList.tail; while ( state != last ) { /* Move forward and load up the next. */ state = next; next = state->next; /* Throw to the end? */ if ( state->isFinState() ) { stateList.detach( state ); stateList.append( state ); } } } void FsmAp::setStateNumbers( int base ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) state->alg.stateNum = base++; } bool FsmAp::checkErrTrans( StateAp *state, TransAp *trans ) { /* Might go directly to error state. */ if ( trans->toState == 0 ) return true; if ( trans->prev == 0 ) { /* If this is the first transition. */ if ( keyOps->minKey < trans->lowKey ) return true; } else { /* Not the first transition. Compare against the prev. */ TransAp *prev = trans->prev; Key nextKey = prev->highKey; nextKey.increment(); if ( nextKey < trans->lowKey ) return true; } return false; } bool FsmAp::checkErrTransFinish( StateAp *state ) { /* Check if there are any ranges already. */ if ( state->outList.length() == 0 ) return true; else { /* Get the last and check for a gap on the end. */ TransAp *last = state->outList.tail; if ( last->highKey < keyOps->maxKey ) return true; } return 0; } bool FsmAp::hasErrorTrans() { bool result; for ( StateList::Iter st = stateList; st.lte(); st++ ) { for ( TransList::Iter tr = st->outList; tr.lte(); tr++ ) { result = checkErrTrans( st, tr ); if ( result ) return true; } result = checkErrTransFinish( st ); if ( result ) return true; } return false; } ragel-6.10/ragel/rubyftable.h0000664000175000017500000000362413065111230013054 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RUBY_FTABCODEGEN_H #define _RUBY_FTABCODEGEN_H #include "rubytable.h" class RubyFTabCodeGen : public RubyTabCodeGen { public: RubyFTabCodeGen( ostream &out ): RubyTabCodeGen(out) {} protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); void GOTO( ostream &out, int gotoDest, bool inFinish ); void GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ); void CALL( ostream &out, int callDest, int targState, bool inFinish ); void CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ); void RET( ostream &out, bool inFinish ); void BREAK( ostream &out, int targState ); int TO_STATE_ACTION( RedStateAp *state ); int FROM_STATE_ACTION( RedStateAp *state ); int EOF_ACTION( RedStateAp *state ); virtual int TRANS_ACTION( RedTransAp *trans ); void writeData(); void writeExec(); void calcIndexSize(); }; /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ #endif ragel-6.10/ragel/rlparse.cpp0000664000175000017500000065502013065122655012740 00000000000000/* Automatically generated by Kelbt from "rlparse.kl". * * Parts of this file are copied from Kelbt source covered by the GNU * GPL. As a special exception, you may use the parts of this file copied * from Kelbt source without restriction. The remainder is derived from * "rlparse.kl" and inherits the copyright status of that file. */ #line 1 "rlparse.kl" /* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rlparse.h" #include "ragel.h" #include #include #include using std::cout; using std::cerr; using std::endl; #line 102 "rlparse.kh" #line 105 "rlparse.kh" #line 140 "rlparse.kh" #line 1444 "rlparse.kl" #line 48 "rlparse.cpp" struct Parser_Lel_action_ref { #line 755 "rlparse.kl" Action *action; #line 54 "rlparse.cpp" }; struct Parser_Lel_aug_type { #line 546 "rlparse.kl" InputLoc loc; AugType augType; #line 65 "rlparse.cpp" }; struct Parser_Lel_expression { #line 338 "rlparse.kl" Expression *expression; #line 75 "rlparse.cpp" }; struct Parser_Lel_factor { #line 975 "rlparse.kl" Factor *factor; #line 85 "rlparse.cpp" }; struct Parser_Lel_factor_rep_num { #line 929 "rlparse.kl" int rep; #line 95 "rlparse.cpp" }; struct Parser_Lel_factor_with_aug { #line 452 "rlparse.kl" FactorWithAug *factorWithAug; #line 105 "rlparse.cpp" }; struct Parser_Lel_factor_with_ep { #line 436 "rlparse.kl" FactorWithAug *factorWithAug; #line 115 "rlparse.cpp" }; struct Parser_Lel_factor_with_label { #line 420 "rlparse.kl" FactorWithAug *factorWithAug; #line 125 "rlparse.cpp" }; struct Parser_Lel_factor_with_neg { #line 939 "rlparse.kl" FactorWithNeg *factorWithNeg; #line 135 "rlparse.cpp" }; struct Parser_Lel_factor_with_rep { #line 868 "rlparse.kl" FactorWithRep *factorWithRep; #line 145 "rlparse.cpp" }; struct Parser_Lel_inline_item { #line 1234 "rlparse.kl" InlineItem *inlineItem; #line 155 "rlparse.cpp" }; struct Parser_Lel_inline_list { #line 1213 "rlparse.kl" InlineList *inlineList; #line 165 "rlparse.cpp" }; struct Parser_Lel_join { #line 321 "rlparse.kl" Join *join; #line 175 "rlparse.cpp" }; struct Parser_Lel_join_or_lm { #line 229 "rlparse.kl" MachineDef *machineDef; #line 185 "rlparse.cpp" }; struct Parser_Lel_lm_part_list { #line 253 "rlparse.kl" LmPartList *lmPartList; #line 195 "rlparse.cpp" }; struct Parser_Lel_local_err_name { #line 856 "rlparse.kl" int error_name; #line 205 "rlparse.cpp" }; struct Parser_Lel_longest_match_part { #line 277 "rlparse.kl" LongestMatchPart *lmPart; #line 215 "rlparse.cpp" }; struct Parser_Lel_opt_export { #line 95 "rlparse.kl" bool isSet; #line 225 "rlparse.cpp" }; struct Parser_Lel_opt_lm_part_action { #line 294 "rlparse.kl" Action *action; #line 235 "rlparse.cpp" }; struct Parser_Lel_priority_aug { #line 803 "rlparse.kl" int priorityNum; #line 245 "rlparse.cpp" }; struct Parser_Lel_priority_name { #line 788 "rlparse.kl" int priorityName; #line 255 "rlparse.cpp" }; struct Parser_Lel_range_lit { #line 1042 "rlparse.kl" Literal *literal; #line 265 "rlparse.cpp" }; struct Parser_Lel_regular_expr { #line 1079 "rlparse.kl" RegExpr *regExpr; #line 275 "rlparse.cpp" }; struct Parser_Lel_regular_expr_char { #line 1131 "rlparse.kl" ReItem *reItem; #line 285 "rlparse.cpp" }; struct Parser_Lel_regular_expr_item { #line 1114 "rlparse.kl" ReItem *reItem; #line 295 "rlparse.cpp" }; struct Parser_Lel_regular_expr_or_char { #line 1188 "rlparse.kl" ReOrItem *reOrItem; #line 305 "rlparse.cpp" }; struct Parser_Lel_regular_expr_or_data { #line 1155 "rlparse.kl" ReOrBlock *reOrBlock; #line 315 "rlparse.cpp" }; struct Parser_Lel_term { #line 389 "rlparse.kl" Term *term; #line 325 "rlparse.cpp" }; struct Parser_Lel_term_short { #line 368 "rlparse.kl" Term *term; #line 335 "rlparse.cpp" }; struct Parser_Lel_token_type { #line 146 "rlparse.kl" Token token; #line 345 "rlparse.cpp" }; union Parser_UserData { struct Parser_Lel_action_ref action_ref; struct Parser_Lel_aug_type aug_type; struct Parser_Lel_expression expression; struct Parser_Lel_factor factor; struct Parser_Lel_factor_rep_num factor_rep_num; struct Parser_Lel_factor_with_aug factor_with_aug; struct Parser_Lel_factor_with_ep factor_with_ep; struct Parser_Lel_factor_with_label factor_with_label; struct Parser_Lel_factor_with_neg factor_with_neg; struct Parser_Lel_factor_with_rep factor_with_rep; struct Parser_Lel_inline_item inline_item; struct Parser_Lel_inline_list inline_list; struct Parser_Lel_join join; struct Parser_Lel_join_or_lm join_or_lm; struct Parser_Lel_lm_part_list lm_part_list; struct Parser_Lel_local_err_name local_err_name; struct Parser_Lel_longest_match_part longest_match_part; struct Parser_Lel_opt_export opt_export; struct Parser_Lel_opt_lm_part_action opt_lm_part_action; struct Parser_Lel_priority_aug priority_aug; struct Parser_Lel_priority_name priority_name; struct Parser_Lel_range_lit range_lit; struct Parser_Lel_regular_expr regular_expr; struct Parser_Lel_regular_expr_char regular_expr_char; struct Parser_Lel_regular_expr_item regular_expr_item; struct Parser_Lel_regular_expr_or_char regular_expr_or_char; struct Parser_Lel_regular_expr_or_data regular_expr_or_data; struct Parser_Lel_term term; struct Parser_Lel_term_short term_short; struct Parser_Lel_token_type token_type; struct Token token; }; struct Parser_LangEl { char *file; int line; int type; int reduction; int state; int causeReduce; union Parser_UserData user; unsigned int retry; struct Parser_LangEl *next, *child, *prev; }; struct Parser_Block { struct Parser_LangEl data[8128]; struct Parser_Block *next; }; #line 404 "rlparse.cpp" unsigned int Parser_startState = 0; short Parser_indicies[] = { 152, -1, -1, 152, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 152, 152, 152, 152, -1, -1, -1, -1, -1, -1, -1, -1, 152, 152, 152, 152, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 152, 152, 152, 1, 0, 404, 154, -1, -1, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, 154, 154, 154, -1, -1, -1, -1, -1, -1, -1, -1, 154, 154, 154, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, 154, 150, -1, -1, 2, 161, -1, -1, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, 158, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 8, -1, -1, -1, -1, 153, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, 10, 3, 165, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 14, 15, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, 174, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 174, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, 25, -1, -1, -1, -1, 159, 20, 21, 22, 27, 168, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, 327, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 170, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 342, 342, 342, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, 342, -1, -1, -1, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31, 342, 342, 342, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, 342, -1, -1, -1, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, 155, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 173, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 171, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 154, -1, -1, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, 154, 154, 154, -1, -1, -1, -1, -1, -1, -1, -1, 154, 154, 154, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, 154, -1, -1, -1, 34, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, 342, 342, 342, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, 342, -1, -1, -1, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, 167, 169, 38, 348, 349, 350, -1, 346, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 156, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 351, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, 40, 39, 380, 381, 41, 43, 44, 382, 383, 30, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 341, 345, 343, 344, 352, 348, 349, 350, -1, 346, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 157, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 351, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, 40, 39, 380, 381, 41, 43, 44, 382, 383, 30, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 341, 345, 343, 344, 352, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 162, -1, -1, 161, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, 158, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 8, -1, -1, -1, -1, 153, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, 10, 3, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 47, -1, 58, -1, -1, -1, -1, -1, -1, -1, 48, 191, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 64, 58, -1, -1, -1, -1, -1, -1, -1, 48, 191, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 348, 349, 350, -1, 346, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 166, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 351, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, 40, 39, 380, 381, 41, 43, 44, 382, 383, 30, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 341, 345, 343, 344, 352, 389, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 388, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67, -1, -1, -1, -1, 68, 353, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 69, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 389, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 388, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 70, -1, -1, -1, -1, 68, 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 389, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 388, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, -1, -1, -1, -1, 68, 73, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 389, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 388, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, -1, -1, -1, -1, 68, 361, 362, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 172, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 81, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 163, 83, -1, -1, 186, -1, -1, 186, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 186, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 186, 82, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 186, -1, -1, -1, -1, 85, 55, -1, -1, -1, -1, 192, -1, 63, 192, -1, -1, 192, 18, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, 192, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, 87, 88, 89, -1, 192, -1, -1, -1, -1, 192, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 193, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 315, -1, -1, 315, 315, 315, -1, 315, 315, 315, 315, 315, 315, 315, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, 315, 315, -1, 315, 315, 315, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 315, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 315, 315, -1, -1, -1, 315, 315, -1, -1, 315, 315, -1, 315, 315, 315, 315, 315, 315, -1, -1, -1, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 315, 315, 315, 200, -1, -1, -1, -1, 200, -1, 200, 200, -1, -1, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 200, 200, -1, -1, -1, 200, 200, -1, -1, 200, 200, -1, 200, 200, 200, 90, 200, -1, -1, -1, -1, 200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 200, 200, 200, 202, -1, -1, 100, 99, 202, -1, 202, 202, -1, -1, 202, 202, 202, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 202, 102, -1, 101, -1, 98, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 202, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 202, 202, -1, -1, -1, 202, 202, -1, -1, 202, 202, -1, 202, 202, 202, 202, 202, -1, -1, -1, -1, 202, 219, 221, 223, 103, 264, 268, 270, 272, 266, 274, 276, 280, 282, 284, 278, 286, 252, 256, 258, 260, 254, 262, 228, 232, 234, 236, 230, 238, 240, 244, 246, 248, 242, 250, 202, 202, 202, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 226, 225, 227, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, 92, 93, 94, 95, 96, 97, 214, -1, -1, 214, 214, 214, -1, 214, 214, 300, 303, 214, 214, 214, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 214, 214, -1, 214, 302, 214, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 214, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, 214, -1, -1, -1, 214, 214, -1, -1, 214, 214, -1, 214, 214, 214, 214, 214, 301, -1, -1, -1, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 214, 214, 214, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 310, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 311, 312, -1, -1, 62, 313, -1, -1, 313, 313, 313, -1, 313, 313, 313, 313, 313, 313, 313, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 313, 313, -1, 313, 313, 313, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 313, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 313, 313, -1, -1, -1, 313, 313, -1, -1, 313, 313, 322, 313, 313, 313, 313, 313, 313, -1, -1, -1, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 313, 313, 313, 314, -1, -1, 314, 314, 314, -1, 314, 314, 314, 314, 314, 314, 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, 314, -1, 314, 314, 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, 314, -1, -1, -1, 314, 314, -1, -1, 314, 314, 324, 314, 314, 314, 314, 314, 314, -1, -1, -1, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 314, 314, 314, 338, -1, -1, -1, 338, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 79, 338, -1, -1, -1, 338, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 80, 330, 330, 330, -1, 330, -1, -1, 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 78, 105, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 76, -1, 58, -1, -1, -1, -1, -1, -1, -1, 48, 191, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 164, 81, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 175, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 158, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 180, -1, 179, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 160, 108, -1, 107, -1, 58, -1, -1, 106, 178, -1, -1, -1, 48, 191, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 384, 391, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 355, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 110, 359, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 111, 357, 364, 364, 364, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 364, 364, -1, -1, -1, 364, 364, 364, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112, 321, -1, -1, 81, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 319, 114, 115, -1, 335, -1, -1, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 329, 113, 317, -1, -1, -1, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 337, 318, -1, -1, -1, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 337, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, 117, 191, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, 187, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, 188, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, 189, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, 190, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 194, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 195, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 55, -1, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 197, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 386, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 201, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 118, 119, -1, -1, 121, -1, 122, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, 296, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 203, 290, -1, -1, -1, -1, -1, -1, -1, -1, 204, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 295, 123, -1, -1, -1, -1, -1, -1, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 206, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 208, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 209, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 210, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 211, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 125, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 212, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 215, -1, -1, 215, -1, 215, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 215, -1, -1, -1, -1, 215, -1, -1, -1, 215, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 261, 273, 285, 237, 249, 216, -1, -1, 216, -1, 216, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 216, -1, -1, -1, -1, 216, -1, -1, -1, 216, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 224, -1, 259, 271, 283, 235, 247, 217, -1, -1, 217, -1, 217, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 217, -1, -1, -1, -1, 217, -1, -1, -1, 217, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 222, -1, 257, 269, 281, 233, 245, 218, -1, -1, 218, -1, 218, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 218, -1, -1, -1, -1, 218, -1, -1, -1, 218, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 220, -1, 253, 265, 277, 229, 241, 255, 267, 279, 231, 243, 263, 275, 287, 239, 251, 127, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 126, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 323, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 325, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 320, 55, -1, -1, -1, -1, -1, -1, 63, -1, 131, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 57, -1, -1, 326, 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 158, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 180, -1, 179, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 160, 108, -1, 107, -1, 58, -1, -1, -1, 177, -1, -1, -1, 48, 191, 49, 198, 52, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, 308, 312, -1, -1, 62, 81, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 184, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 130, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 129, -1, 183, 165, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 128, 387, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 387, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 356, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 376, 377, 378, -1, 375, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, 381, -1, -1, -1, 382, 383, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 365, -1, 367, -1, 363, 366, 332, 332, 332, -1, 332, 331, -1, 332, 338, -1, -1, -1, 338, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133, 338, -1, -1, -1, 338, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134, 339, -1, -1, 135, 339, 83, -1, -1, 185, -1, -1, 185, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 185, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 185, 82, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 185, -1, -1, -1, -1, 85, 391, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 136, 139, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 137, -1, -1, -1, -1, -1, -1, -1, -1, 138, 342, 342, 342, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, 342, -1, -1, -1, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 140, 297, 298, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 207, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 138, 142, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 141, -1, 138, 144, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 304, 309, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 143, 35, 181, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 182, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 176, 390, 333, -1, -1, -1, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 337, 334, -1, -1, -1, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 337, 340, 385, -1, -1, -1, -1, 385, -1, 385, 385, -1, -1, 385, 385, 385, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 385, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 385, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 385, 385, -1, -1, -1, 385, 385, -1, -1, 385, 385, -1, 385, 385, 385, 385, 385, -1, -1, 132, -1, 385, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 385, 385, 385, 145, 289, 291, -1, -1, 294, 348, 349, 350, -1, 346, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 347, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 293, -1, -1, 374, -1, -1, -1, 372, 373, -1, -1, -1, -1, -1, -1, -1, -1, 351, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, 369, 370, 371, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, 40, 39, 380, 381, 41, 43, 44, 382, 383, 30, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 341, 345, 343, 344, 352, 146, 291, -1, -1, 299, 305, 306, -1, -1, -1, -1, -1, -1, 309, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 147, 121, -1, 122, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 296, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 148, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 295, 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 149, 290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 288, 307, 205, 213, }; unsigned short Parser_keys[] = { 128, 227, 225, 225, 128, 228, 128, 244, 128, 245, 128, 128, 128, 128, 45, 248, 40, 249, 40, 249, 128, 250, 123, 128, 123, 123, 123, 123, 128, 128, 123, 123, 59, 128, 45, 248, 132, 132, 40, 292, 40, 242, 40, 242, 59, 59, 128, 187, 40, 292, 125, 228, 61, 141, 40, 242, 59, 59, 59, 59, 40, 40, 40, 289, 40, 289, 40, 249, 125, 244, 33, 281, 33, 281, 40, 289, 128, 295, 59, 59, 40, 249, 42, 295, 42, 295, 42, 295, 59, 59, 59, 59, 40, 292, 44, 59, 38, 144, 33, 281, 33, 201, 33, 181, 33, 271, 33, 201, 33, 281, 33, 281, 33, 201, 33, 201, 182, 279, 182, 279, 179, 280, 134, 134, 33, 281, 59, 59, 44, 59, 33, 281, 41, 41, 128, 294, 40, 292, 59, 59, 40, 249, 59, 59, 40, 249, 59, 59, 40, 249, 41, 44, 33, 281, 179, 283, 182, 284, 182, 284, 33, 281, 33, 281, 33, 281, 33, 281, 33, 281, 33, 281, 33, 281, 33, 281, 33, 281, 128, 293, 40, 275, 33, 274, 40, 274, 40, 274, 40, 274, 40, 274, 40, 274, 40, 206, 40, 206, 40, 206, 40, 206, 202, 206, 202, 206, 44, 276, 45, 281, 33, 281, 44, 255, 128, 245, 41, 142, 40, 292, 40, 292, 40, 292, 179, 186, 182, 279, 182, 279, 182, 186, 38, 144, 128, 294, 128, 274, 40, 242, 132, 132, 132, 132, 40, 274, 128, 274, 128, 274, 44, 125, 132, 276, 61, 61, 59, 59, 40, 274, 124, 124, 128, 128, 182, 284, 182, 284, 186, 186, 33, 181, 44, 44, 41, 41, 41, 44, 40, 289, 44, 44, 41, 44, 125, 125, 125, 276, 43, 275, 40, 274, 125, 125, 41, 41, 41, 41, 0, 0 }; unsigned int Parser_offsets[] = { 0, 100, 101, 202, 319, 437, 438, 439, 643, 853, 1063, 1186, 1192, 1193, 1194, 1195, 1196, 1266, 1470, 1471, 1724, 1927, 2130, 2131, 2191, 2444, 2548, 2629, 2832, 2833, 2834, 2835, 3085, 3335, 3545, 3665, 3914, 4163, 4413, 4581, 4582, 4792, 5046, 5300, 5554, 5555, 5556, 5809, 5825, 5932, 6181, 6350, 6499, 6738, 6907, 7156, 7405, 7574, 7743, 7841, 7939, 8041, 8042, 8291, 8292, 8308, 8557, 8558, 8725, 8978, 8979, 9189, 9190, 9400, 9401, 9611, 9615, 9864, 9969, 10072, 10175, 10424, 10673, 10922, 11171, 11420, 11669, 11918, 12167, 12416, 12582, 12818, 13060, 13295, 13530, 13765, 14000, 14235, 14402, 14569, 14736, 14903, 14908, 14913, 15146, 15383, 15632, 15844, 15962, 16064, 16317, 16570, 16823, 16831, 16929, 17027, 17032, 17139, 17306, 17453, 17656, 17657, 17658, 17893, 18040, 18187, 18269, 18414, 18415, 18416, 18651, 18652, 18653, 18756, 18859, 18860, 19009, 19010, 19011, 19015, 19265, 19266, 19270, 19271, 19423, 19656, 19891, 19892, 19893, 19894 }; unsigned short Parser_targs[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149 }; unsigned int Parser_actInds[] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, 471, 473, 475, 477, 479, 481, 483, 485, 487, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537, 539, 541, 543, 545, 547, 549, 551, 553, 555, 557, 559, 561, 563, 565, 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, 587, 589, 591, 593, 595, 597, 599, 601, 603, 605, 607, 609, 611, 613, 615, 617, 619, 621, 623, 625, 627, 629, 631, 633, 635, 637, 639, 641, 643, 645, 647, 649, 651, 653, 655, 657, 659, 661, 663, 665, 667, 669, 671, 673, 675, 677, 679, 681, 683, 685, 687, 689, 691, 693, 695, 697, 699, 701, 703, 705, 707, 709, 711, 713, 715, 717, 719, 721, 723, 725, 727, 729, 731, 733, 735, 737, 739, 741, 743, 745, 747, 749, 751, 753, 755, 757, 759, 761, 763, 765, 767, 769, 771, 773, 775, 777, 779, 781, 783, 785, 787, 789, 791, 793, 795, 797, 799, 801, 803, 805, 807, 809, 811 }; unsigned int Parser_actions[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 214, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 90, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 302, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 0, 7, 0, 10, 0, 15, 0, 18, 0, 71, 0, 75, 0, 79, 0, 83, 0, 86, 0, 87, 0, 90, 0, 95, 0, 99, 0, 103, 0, 107, 0, 111, 0, 115, 0, 119, 0, 123, 0, 127, 0, 131, 0, 135, 0, 139, 0, 142, 0, 146, 0, 151, 0, 155, 0, 159, 0, 163, 0, 167, 0, 171, 0, 175, 0, 179, 0, 182, 0, 186, 0, 190, 0, 195, 0, 199, 0, 203, 0, 207, 0, 211, 0, 214, 0, 219, 0, 223, 0, 227, 0, 231, 0, 235, 0, 239, 0, 243, 0, 246, 0, 251, 0, 254, 0, 259, 0, 263, 0, 267, 0, 271, 0, 275, 0, 279, 0, 283, 0, 287, 0, 291, 0, 295, 0, 299, 0, 302, 0, 306, 0, 310, 0, 314, 0, 318, 0, 323, 0, 327, 0, 331, 0, 335, 0, 339, 0, 343, 0, 347, 0, 351, 0, 355, 0, 359, 0, 363, 0, 367, 0, 371, 0, 375, 0, 379, 0, 383, 0, 387, 0, 391, 0, 395, 0, 399, 0, 403, 0, 407, 0, 411, 0, 415, 0, 419, 0, 423, 0, 427, 0, 431, 0, 435, 0, 439, 0, 443, 0, 447, 0, 451, 0, 455, 0, 459, 0, 463, 0, 467, 0, 471, 0, 475, 0, 479, 0, 483, 0, 487, 0, 491, 0, 495, 0, 499, 0, 503, 0, 507, 0, 511, 0, 515, 0, 519, 0, 523, 0, 527, 0, 531, 0, 535, 0, 539, 0, 543, 0, 547, 0, 551, 0, 555, 0, 559, 0, 563, 0, 567, 0, 571, 0, 575, 0, 579, 0, 583, 0, 587, 0, 591, 0, 595, 0, 599, 0, 603, 0, 607, 0, 610, 0, 611, 0, 615, 0, 618, 0, 623, 0, 627, 0, 631, 0, 635, 0, 638, 0, 643, 0, 647, 0, 651, 0, 655, 0, 659, 0, 663, 0, 667, 0, 671, 0, 675, 0, 679, 0, 683, 0, 687, 0, 691, 0, 694, 0, 698, 0, 702, 0, 703, 0, 707, 0, 711, 0, 715, 0, 719, 0, 723, 0, 726, 0, 727, 0, 730, 0, 731, 0, 735, 0, 739, 0, 743, 0, 747, 0, 750, 0, 755, 0, 758, 0, 763, 0, 767, 0, 771, 0, 775, 0, 779, 0, 782, 0, 786, 0, 791, 0, 795, 0, 798, 0, 803, 0, 807, 0, 811, 0, 815, 0, 819, 0, 823, 0, 827, 0, 831, 0, 835, 0, 839, 0, 843, 0, 847, 0, 851, 0, 855, 0, 859, 0, 863, 0, 867, 0, 871, 0, 875, 0, 879, 0, 883, 0, 886, 0, 891, 0, 895, 0, 899, 0, 903, 0, 907, 0, 911, 0, 915, 0, 919, 0, 923, 0, 927, 0, 931, 0, 935, 0, 939, 0, 943, 0, 947, 0, 951, 0, 955, 0, 959, 0, 963, 0, 967, 0, 970, 0, 974, 0, 978, 0, 983, 0, 986, 0, 991, 0, 995, 0, 23, 0, 27, 0, 31, 0, 35, 0, 39, 0, 43, 0, 47, 0, 51, 0, 55, 0, 59, 0, 63, 0, 67, 0, 1, 0 }; int Parser_commitLen[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 }; char Parser_prodLengths[] = { 1, 3, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 4, 1, 1, 0, 4, 5, 5, 1, 5, 4, 3, 4, 3, 3, 5, 2, 0, 1, 4, 2, 1, 1, 1, 3, 2, 1, 0, 3, 1, 3, 3, 3, 3, 1, 1, 2, 3, 3, 3, 3, 1, 3, 1, 3, 1, 3, 3, 7, 3, 4, 3, 3, 3, 3, 3, 7, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 1, 3, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 4, 5, 5, 6, 1, 1, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 2, 1, 2, 0, 2, 1, 3, 3, 1, 1, 2, 0, 1, 3, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 3, 4, 3, 4, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 2, 0, 2, 1, 0, 3, 1, 1 }; unsigned short Parser_prodLhsIds[] = { 227, 226, 226, 228, 228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 241, 239, 240, 243, 244, 244, 238, 230, 231, 245, 232, 233, 233, 234, 235, 236, 237, 250, 250, 247, 247, 251, 251, 252, 252, 252, 253, 253, 253, 246, 246, 256, 256, 256, 256, 256, 257, 258, 258, 258, 258, 258, 258, 259, 259, 260, 260, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 263, 263, 263, 263, 266, 266, 266, 266, 266, 266, 266, 266, 266, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 254, 254, 254, 274, 255, 265, 264, 275, 275, 275, 272, 273, 273, 273, 273, 273, 273, 273, 273, 273, 276, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 281, 281, 248, 248, 248, 280, 280, 282, 282, 283, 283, 283, 283, 279, 279, 284, 284, 242, 242, 285, 285, 285, 288, 288, 288, 288, 288, 288, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 249, 249, 291, 291, 291, 287, 287, 287, 287, 287, 287, 287, 292, 292, 292, 292, 292, 289, 289, 289, 289, 289, 261, 293, 290, 295, 295, 294, 294, 296 }; const char *Parser_prodNames[] = { "start-1", "section_list-1", "section_list-2", "statement_list-1", "statement_list-2", "statement-1", "statement-2", "statement-3", "statement-4", "statement-5", "statement-6", "statement-7", "statement-8", "statement-9", "statement-10", "statement-11", "statement-12", "length_spec-1", "pre_push_spec-1", "post_pop_spec-1", "export_open-1", "opt_export-1", "opt_export-2", "export_block-1", "assignment-1", "instantiation-1", "machine_name-1", "action_spec-1", "alphtype_spec-1", "alphtype_spec-2", "range_spec-1", "getkey_spec-1", "access_spec-1", "variable_spec-1", "opt_whitespace-1", "opt_whitespace-2", "join_or_lm-1", "join_or_lm-2", "lm_part_list-1", "lm_part_list-2", "longest_match_part-1", "longest_match_part-2", "longest_match_part-3", "opt_lm_part_action-1", "opt_lm_part_action-2", "opt_lm_part_action-3", "join-1", "join-2", "expression-1", "expression-2", "expression-3", "expression-4", "expression-5", "term_short-1", "term-1", "term-2", "term-3", "term-4", "term-5", "term-6", "factor_with_label-1", "factor_with_label-2", "factor_with_ep-1", "factor_with_ep-2", "factor_with_aug-1", "factor_with_aug-2", "factor_with_aug-3", "factor_with_aug-4", "factor_with_aug-5", "factor_with_aug-6", "factor_with_aug-7", "factor_with_aug-8", "factor_with_aug-9", "factor_with_aug-10", "factor_with_aug-11", "factor_with_aug-12", "aug_type_base-1", "aug_type_base-2", "aug_type_base-3", "aug_type_base-4", "aug_type_cond-1", "aug_type_cond-2", "aug_type_cond-3", "aug_type_cond-4", "aug_type_cond-5", "aug_type_cond-6", "aug_type_cond-7", "aug_type_cond-8", "aug_type_cond-9", "aug_type_to_state-1", "aug_type_to_state-2", "aug_type_to_state-3", "aug_type_to_state-4", "aug_type_to_state-5", "aug_type_to_state-6", "aug_type_to_state-7", "aug_type_to_state-8", "aug_type_to_state-9", "aug_type_to_state-10", "aug_type_to_state-11", "aug_type_to_state-12", "aug_type_from_state-1", "aug_type_from_state-2", "aug_type_from_state-3", "aug_type_from_state-4", "aug_type_from_state-5", "aug_type_from_state-6", "aug_type_from_state-7", "aug_type_from_state-8", "aug_type_from_state-9", "aug_type_from_state-10", "aug_type_from_state-11", "aug_type_from_state-12", "aug_type_eof-1", "aug_type_eof-2", "aug_type_eof-3", "aug_type_eof-4", "aug_type_eof-5", "aug_type_eof-6", "aug_type_eof-7", "aug_type_eof-8", "aug_type_eof-9", "aug_type_eof-10", "aug_type_eof-11", "aug_type_eof-12", "aug_type_gbl_error-1", "aug_type_gbl_error-2", "aug_type_gbl_error-3", "aug_type_gbl_error-4", "aug_type_gbl_error-5", "aug_type_gbl_error-6", "aug_type_gbl_error-7", "aug_type_gbl_error-8", "aug_type_gbl_error-9", "aug_type_gbl_error-10", "aug_type_gbl_error-11", "aug_type_gbl_error-12", "aug_type_local_error-1", "aug_type_local_error-2", "aug_type_local_error-3", "aug_type_local_error-4", "aug_type_local_error-5", "aug_type_local_error-6", "aug_type_local_error-7", "aug_type_local_error-8", "aug_type_local_error-9", "aug_type_local_error-10", "aug_type_local_error-11", "aug_type_local_error-12", "action_embed-1", "action_embed-2", "action_embed-3", "action_embed_word-1", "action_embed_block-1", "priority_name-1", "priority_aug-1", "priority_aug_num-1", "priority_aug_num-2", "priority_aug_num-3", "local_err_name-1", "factor_with_rep-1", "factor_with_rep-2", "factor_with_rep-3", "factor_with_rep-4", "factor_with_rep-5", "factor_with_rep-6", "factor_with_rep-7", "factor_with_rep-8", "factor_with_rep-9", "factor_rep_num-1", "factor_with_neg-1", "factor_with_neg-2", "factor_with_neg-3", "factor-1", "factor-2", "factor-3", "factor-4", "factor-5", "factor-6", "factor-7", "factor-8", "range_lit-1", "range_lit-2", "alphabet_num-1", "alphabet_num-2", "alphabet_num-3", "regular_expr-1", "regular_expr-2", "regular_expr_item-1", "regular_expr_item-2", "regular_expr_char-1", "regular_expr_char-2", "regular_expr_char-3", "regular_expr_char-4", "regular_expr_or_data-1", "regular_expr_or_data-2", "regular_expr_or_char-1", "regular_expr_or_char-2", "inline_block-1", "inline_block-2", "inline_block_item-1", "inline_block_item-2", "inline_block_item-3", "inline_block_symbol-1", "inline_block_symbol-2", "inline_block_symbol-3", "inline_block_symbol-4", "inline_block_symbol-5", "inline_block_symbol-6", "inline_block_interpret-1", "inline_block_interpret-2", "inline_block_interpret-3", "inline_block_interpret-4", "inline_block_interpret-5", "inline_block_interpret-6", "inline_block_interpret-7", "inline_block_interpret-8", "inline_block_interpret-9", "inline_block_interpret-10", "inline_block_interpret-11", "inline_expr-1", "inline_expr-2", "inline_expr_item-1", "inline_expr_item-2", "inline_expr_item-3", "inline_expr_any-1", "inline_expr_any-2", "inline_expr_any-3", "inline_expr_any-4", "inline_expr_any-5", "inline_expr_any-6", "inline_expr_any-7", "inline_expr_symbol-1", "inline_expr_symbol-2", "inline_expr_symbol-3", "inline_expr_symbol-4", "inline_expr_symbol-5", "inline_expr_interpret-1", "inline_expr_interpret-2", "inline_expr_interpret-3", "inline_expr_interpret-4", "inline_expr_interpret-5", "local_state_ref-1", "no_name_sep-1", "state_ref-1", "opt_name_sep-1", "opt_name_sep-2", "state_ref_names-1", "state_ref_names-2", "_start-1" }; const char *Parser_lelNames[] = { "D-0", "D-1", "D-2", "D-3", "D-4", "D-5", "D-6", "D-7", "D-8", "D-9", "D-10", "D-11", "D-12", "D-13", "D-14", "D-15", "D-16", "D-17", "D-18", "D-19", "D-20", "D-21", "D-22", "D-23", "D-24", "D-25", "D-26", "D-27", "D-28", "D-29", "D-30", "D-31", "D-32", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "D-127", "TK_Word", "TK_Literal", "TK_Number", "TK_EndSection", "TK_UInt", "TK_Hex", "TK_DotDot", "TK_ColonGt", "TK_ColonGtGt", "TK_LtColon", "TK_Arrow", "TK_DoubleArrow", "TK_StarStar", "TK_ColonEquals", "TK_NameSep", "TK_BarStar", "TK_DashDash", "TK_StartCond", "TK_AllCond", "TK_LeavingCond", "TK_Middle", "TK_StartGblError", "TK_AllGblError", "TK_FinalGblError", "TK_NotFinalGblError", "TK_NotStartGblError", "TK_MiddleGblError", "TK_StartLocalError", "TK_AllLocalError", "TK_FinalLocalError", "TK_NotFinalLocalError", "TK_NotStartLocalError", "TK_MiddleLocalError", "TK_StartEOF", "TK_AllEOF", "TK_FinalEOF", "TK_NotFinalEOF", "TK_NotStartEOF", "TK_MiddleEOF", "TK_StartToState", "TK_AllToState", "TK_FinalToState", "TK_NotFinalToState", "TK_NotStartToState", "TK_MiddleToState", "TK_StartFromState", "TK_AllFromState", "TK_FinalFromState", "TK_NotFinalFromState", "TK_NotStartFromState", "TK_MiddleFromState", "RE_Slash", "RE_SqOpen", "RE_SqOpenNeg", "RE_SqClose", "RE_Dot", "RE_Star", "RE_Dash", "RE_Char", "IL_WhiteSpace", "IL_Comment", "IL_Literal", "IL_Symbol", "KW_Machine", "KW_Include", "KW_Import", "KW_Write", "KW_Action", "KW_AlphType", "KW_Range", "KW_GetKey", "KW_InWhen", "KW_When", "KW_OutWhen", "KW_Eof", "KW_Err", "KW_Lerr", "KW_To", "KW_From", "KW_Export", "KW_PrePush", "KW_PostPop", "KW_Length", "KW_Break", "KW_Exec", "KW_Hold", "KW_PChar", "KW_Char", "KW_Goto", "KW_Call", "KW_Ret", "KW_CurState", "KW_TargState", "KW_Entry", "KW_Next", "KW_Variable", "KW_Access", "Parser_tk_eof", "section_list", "start", "statement_list", "statement", "assignment", "instantiation", "action_spec", "alphtype_spec", "range_spec", "getkey_spec", "access_spec", "variable_spec", "export_block", "pre_push_spec", "post_pop_spec", "length_spec", "inline_block", "export_open", "opt_export", "machine_name", "join", "join_or_lm", "alphabet_num", "inline_expr", "opt_whitespace", "lm_part_list", "longest_match_part", "opt_lm_part_action", "action_embed", "action_embed_block", "expression", "term_short", "term", "factor_with_label", "factor_with_ep", "local_state_ref", "factor_with_aug", "aug_type_base", "priority_aug", "priority_name", "aug_type_cond", "aug_type_to_state", "aug_type_from_state", "aug_type_eof", "aug_type_gbl_error", "aug_type_local_error", "local_err_name", "factor_with_rep", "action_embed_word", "priority_aug_num", "factor_rep_num", "factor_with_neg", "factor", "regular_expr_or_data", "regular_expr", "range_lit", "regular_expr_item", "regular_expr_char", "regular_expr_or_char", "inline_block_item", "inline_block_interpret", "inline_expr_any", "inline_block_symbol", "inline_expr_interpret", "state_ref", "inline_expr_item", "inline_expr_symbol", "no_name_sep", "state_ref_names", "opt_name_sep", "_start" }; #line 1449 "rlparse.kl" void Parser::init() { #line 3855 "rlparse.cpp" curs = Parser_startState; pool = 0; block = (struct Parser_Block*) malloc( sizeof(struct Parser_Block) ); block->next = 0; freshEl = block->data; #ifdef KELBT_LOG_ACTIONS cerr << "allocating 8128 LangEls" << endl; #endif stackTop = freshEl; stackTop->type = 0; stackTop->state = -1; stackTop->next = 0; stackTop->child = 0; stackTop->causeReduce = 0; freshPos = 1; lastFinal = stackTop; numRetry = 0; numNodes = 0; errCount = 0; #line 1454 "rlparse.kl" } int Parser::parseLangEl( int type, const Token *token ) { #line 3880 "rlparse.cpp" #define reject() induceReject = 1 int pos, targState; unsigned int *action; int rhsLen; struct Parser_LangEl *rhs[32]; struct Parser_LangEl *lel = 0; struct Parser_LangEl *input = 0; struct Parser_LangEl *queue = 0; char induceReject; if ( curs < 0 ) return 0; if ( pool == 0 ) { if ( freshPos == 8128 ) { struct Parser_Block* newBlock = (struct Parser_Block*) malloc( sizeof(struct Parser_Block) ); newBlock->next = block; block = newBlock; freshEl = newBlock->data; #ifdef KELBT_LOG_ACTIONS cerr << "allocating 8128 LangEls" << endl; #endif freshPos = 0; } queue = freshEl + freshPos++; } else { queue = pool; pool = pool->next; } numNodes += 1; queue->type = type; queue->user.token = *token; queue->next = 0; queue->retry = 0; queue->child = 0; queue->causeReduce = 0; again: if ( input == 0 ) { if ( queue == 0 ) goto _out; input = queue; queue = queue->next; input->next = 0; } lel = input; if ( lel->type < Parser_keys[curs<<1] || lel->type > Parser_keys[(curs<<1)+1] ) goto parseError; pos = Parser_indicies[Parser_offsets[curs] + (lel->type - Parser_keys[curs<<1])]; if ( pos < 0 ) goto parseError; induceReject = 0; targState = Parser_targs[pos]; action = Parser_actions + Parser_actInds[pos]; if ( lel->retry & 0x0000ffff ) action += (lel->retry & 0x0000ffff); if ( *action & 0x1 ) { #ifdef KELBT_LOG_ACTIONS cerr << "shifted: " << Parser_lelNames[lel->type]; #endif input = input->next; lel->state = curs; lel->next = stackTop; stackTop = lel; if ( action[1] == 0 ) lel->retry &= 0xffff0000; else { lel->retry += 1; numRetry += 1; #ifdef KELBT_LOG_ACTIONS cerr << " retry: " << stackTop; #endif } #ifdef KELBT_LOG_ACTIONS cerr << endl; #endif } if ( Parser_commitLen[pos] != 0 ) { struct Parser_LangEl *commitHead = stackTop, *lel; int sp = 0, doExec = 0; #ifdef KELBT_LOG_ACTIONS cerr << "commit encountered, executing final actions" << endl; #endif if ( Parser_commitLen[pos] < 0 ) commitHead = commitHead->next; lel = commitHead; commit_head: if ( lel == lastFinal ) { doExec = 1; goto commit_base; } if ( lel->next != 0 ) { sp += 1; lel->next->prev = lel; lel = lel->next; lel->retry = 0; goto commit_head; } commit_reverse: if ( lel->child != 0 ) { sp += 1; lel->child->prev = lel; lel = lel->child; lel->retry = 1; goto commit_head; } commit_upwards: if ( doExec ) { if ( lel->type < 226 ) { } else { struct Parser_LangEl *redLel = lel; if ( redLel->child != 0 ) { int r = Parser_prodLengths[redLel->reduction] - 1; struct Parser_LangEl *rhsEl = redLel->child; while ( rhsEl != 0 ) { rhs[r--] = rhsEl; rhsEl = rhsEl->next; } } switch ( lel->reduction ) { case 17: { Token *__ref0 = (Token*)&rhs[1]->user.token; Token *__ref1 = (Token*)&rhs[1]->user.token; Token *__ref2 = (Token*)&rhs[1]->user.token; #line 61 "rlparse.kl" LengthDef *lengthDef = new LengthDef( (__ref0)->data ); pd->lengthDefList.append( lengthDef ); /* Generic creation of machine for instantiation and assignment. */ MachineDef *machineDef = new MachineDef( lengthDef ); tryMachineDef( (__ref1)->loc, (__ref2)->data, machineDef, false ); #line 4031 "rlparse.cpp" } break; case 18: { Token *__ref0 = (Token*)&rhs[1]->user.token; Parser_Lel_inline_list *__ref1 = (Parser_Lel_inline_list*)&rhs[2]->user.inline_list; #line 72 "rlparse.kl" if ( pd->prePushExpr != 0 ) { /* Recover by just ignoring the duplicate. */ error((__ref0)->loc) << "pre_push code already defined" << endl; } pd->prePushExpr = (__ref1)->inlineList; #line 4046 "rlparse.cpp" } break; case 19: { Token *__ref0 = (Token*)&rhs[1]->user.token; Parser_Lel_inline_list *__ref1 = (Parser_Lel_inline_list*)&rhs[2]->user.inline_list; #line 84 "rlparse.kl" if ( pd->postPopExpr != 0 ) { /* Recover by just ignoring the duplicate. */ error((__ref0)->loc) << "post_pop code already defined" << endl; } pd->postPopExpr = (__ref1)->inlineList; #line 4061 "rlparse.cpp" } break; case 20: { #line 95 "rlparse.kl" exportContext.append( true ); #line 4069 "rlparse.cpp" } break; case 21: { Parser_Lel_opt_export *__ref0 = (Parser_Lel_opt_export*)&redLel->user.opt_export; #line 104 "rlparse.kl" (__ref0)->isSet = true; #line 4076 "rlparse.cpp" } break; case 22: { Parser_Lel_opt_export *__ref0 = (Parser_Lel_opt_export*)&redLel->user.opt_export; #line 105 "rlparse.kl" (__ref0)->isSet = false; #line 4083 "rlparse.cpp" } break; case 23: { #line 108 "rlparse.kl" exportContext.remove( exportContext.length()-1 ); #line 4091 "rlparse.cpp" } break; case 24: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_join *__ref2 = (Parser_Lel_join*)&rhs[3]->user.join; Parser_Lel_token_type *__ref3 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_token_type *__ref4 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_opt_export *__ref5 = (Parser_Lel_opt_export*)&rhs[0]->user.opt_export; Parser_Lel_join *__ref6 = (Parser_Lel_join*)&rhs[3]->user.join; Token *__ref7 = (Token*)&rhs[2]->user.token; #line 113 "rlparse.kl" /* Main machine must be an instance. */ bool isInstance = false; if ( strcmp((__ref0)->token.data, mainMachine) == 0 ) { warning((__ref1)->token.loc) << "main machine will be implicitly instantiated" << endl; isInstance = true; } /* Generic creation of machine for instantiation and assignment. */ MachineDef *machineDef = new MachineDef( (__ref2)->join ); tryMachineDef( (__ref3)->token.loc, (__ref4)->token.data, machineDef, isInstance ); if ( (__ref5)->isSet ) exportContext.remove( exportContext.length()-1 ); (__ref6)->join->loc = (__ref7)->loc; #line 4122 "rlparse.cpp" } break; case 25: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_join_or_lm *__ref2 = (Parser_Lel_join_or_lm*)&rhs[3]->user.join_or_lm; Parser_Lel_opt_export *__ref3 = (Parser_Lel_opt_export*)&rhs[0]->user.opt_export; Parser_Lel_join_or_lm *__ref4 = (Parser_Lel_join_or_lm*)&rhs[3]->user.join_or_lm; Parser_Lel_join_or_lm *__ref5 = (Parser_Lel_join_or_lm*)&rhs[3]->user.join_or_lm; Token *__ref6 = (Token*)&rhs[2]->user.token; #line 133 "rlparse.kl" /* Generic creation of machine for instantiation and assignment. */ tryMachineDef( (__ref0)->token.loc, (__ref1)->token.data, (__ref2)->machineDef, true ); if ( (__ref3)->isSet ) exportContext.remove( exportContext.length()-1 ); /* Pass a location to join_or_lm */ if ( (__ref4)->machineDef->join != 0 ) (__ref5)->machineDef->join->loc = (__ref6)->loc; #line 4145 "rlparse.cpp" } break; case 26: { Token *__ref0 = (Token*)&rhs[0]->user.token; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref3 = (Token*)&rhs[0]->user.token; #line 153 "rlparse.kl" /* Make/get the priority key. The name may have already been referenced * and therefore exist. */ PriorDictEl *priorDictEl; if ( pd->priorDict.insert( (__ref0)->data, pd->nextPriorKey, &priorDictEl ) ) pd->nextPriorKey += 1; pd->curDefPriorKey = priorDictEl->value; /* Make/get the local error key. */ LocalErrDictEl *localErrDictEl; if ( pd->localErrDict.insert( (__ref1)->data, pd->nextLocalErrKey, &localErrDictEl ) ) pd->nextLocalErrKey += 1; pd->curDefLocalErrKey = localErrDictEl->value; (__ref2)->token = *(__ref3); #line 4170 "rlparse.cpp" } break; case 27: { Token *__ref0 = (Token*)&rhs[1]->user.token; Token *__ref1 = (Token*)&rhs[1]->user.token; Token *__ref2 = (Token*)&rhs[1]->user.token; Token *__ref3 = (Token*)&rhs[2]->user.token; Token *__ref4 = (Token*)&rhs[1]->user.token; Parser_Lel_inline_list *__ref5 = (Parser_Lel_inline_list*)&rhs[3]->user.inline_list; #line 171 "rlparse.kl" if ( pd->actionDict.find( (__ref0)->data ) ) { /* Recover by just ignoring the duplicate. */ error((__ref1)->loc) << "action \"" << (__ref2)->data << "\" already defined" << endl; } else { //cerr << "NEW ACTION " << $2->data << " " << $4->inlineList << endl; /* Add the action to the list of actions. */ Action *newAction = new Action( (__ref3)->loc, (__ref4)->data, (__ref5)->inlineList, pd->nextCondId++ ); /* Insert to list and dict. */ pd->actionList.append( newAction ); pd->actionDict.insert( newAction ); } #line 4197 "rlparse.cpp" } break; case 28: { Token *__ref0 = (Token*)&rhs[0]->user.token; Token *__ref1 = (Token*)&rhs[1]->user.token; Token *__ref2 = (Token*)&rhs[2]->user.token; Token *__ref3 = (Token*)&rhs[1]->user.token; Token *__ref4 = (Token*)&rhs[1]->user.token; Token *__ref5 = (Token*)&rhs[2]->user.token; #line 191 "rlparse.kl" if ( ! pd->setAlphType( (__ref0)->loc, (__ref1)->data, (__ref2)->data ) ) { // Recover by ignoring the alphtype statement. error((__ref3)->loc) << "\"" << (__ref4)->data << " " << (__ref5)->data << "\" is not a valid alphabet type" << endl; } #line 4215 "rlparse.cpp" } break; case 29: { Token *__ref0 = (Token*)&rhs[0]->user.token; Token *__ref1 = (Token*)&rhs[1]->user.token; Token *__ref2 = (Token*)&rhs[1]->user.token; Token *__ref3 = (Token*)&rhs[1]->user.token; #line 200 "rlparse.kl" if ( ! pd->setAlphType( (__ref0)->loc, (__ref1)->data ) ) { // Recover by ignoring the alphtype statement. error((__ref2)->loc) << "\"" << (__ref3)->data << "\" is not a valid alphabet type" << endl; } #line 4231 "rlparse.cpp" } break; case 30: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[2]->user.token_type; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&rhs[1]->user.token_type; Parser_Lel_token_type *__ref3 = (Parser_Lel_token_type*)&rhs[2]->user.token_type; #line 210 "rlparse.kl" // Save the upper and lower ends of the range and emit the line number. pd->lowerNum = (__ref0)->token.data; pd->upperNum = (__ref1)->token.data; pd->rangeLowLoc = (__ref2)->token.loc; pd->rangeHighLoc = (__ref3)->token.loc; #line 4247 "rlparse.cpp" } break; case 31: { Parser_Lel_inline_list *__ref0 = (Parser_Lel_inline_list*)&rhs[1]->user.inline_list; #line 219 "rlparse.kl" pd->getKeyExpr = (__ref0)->inlineList; #line 4256 "rlparse.cpp" } break; case 32: { Parser_Lel_inline_list *__ref0 = (Parser_Lel_inline_list*)&rhs[1]->user.inline_list; #line 224 "rlparse.kl" pd->accessExpr = (__ref0)->inlineList; #line 4265 "rlparse.cpp" } break; case 33: { Token *__ref0 = (Token*)&rhs[2]->user.token; Parser_Lel_inline_list *__ref1 = (Parser_Lel_inline_list*)&rhs[3]->user.inline_list; Token *__ref2 = (Token*)&rhs[2]->user.token; #line 229 "rlparse.kl" /* FIXME: Need to implement the rest of this. */ bool wasSet = pd->setVariable( (__ref0)->data, (__ref1)->inlineList ); if ( !wasSet ) error((__ref2)->loc) << "bad variable name" << endl; #line 4279 "rlparse.cpp" } break; case 36: { Parser_Lel_join_or_lm *__ref0 = (Parser_Lel_join_or_lm*)&redLel->user.join_or_lm; Parser_Lel_join *__ref1 = (Parser_Lel_join*)&rhs[0]->user.join; #line 249 "rlparse.kl" (__ref0)->machineDef = new MachineDef( (__ref1)->join ); #line 4289 "rlparse.cpp" } break; case 37: { Token *__ref0 = (Token*)&rhs[0]->user.token; Parser_Lel_lm_part_list *__ref1 = (Parser_Lel_lm_part_list*)&rhs[1]->user.lm_part_list; Parser_Lel_lm_part_list *__ref2 = (Parser_Lel_lm_part_list*)&rhs[1]->user.lm_part_list; Parser_Lel_join_or_lm *__ref3 = (Parser_Lel_join_or_lm*)&redLel->user.join_or_lm; #line 253 "rlparse.kl" /* Create a new factor going to a longest match structure. Record * in the parse data that we have a longest match. */ LongestMatch *lm = new LongestMatch( (__ref0)->loc, (__ref1)->lmPartList ); pd->lmList.append( lm ); for ( LmPartList::Iter lmp = *((__ref2)->lmPartList); lmp.lte(); lmp++ ) lmp->longestMatch = lm; (__ref3)->machineDef = new MachineDef( lm ); #line 4307 "rlparse.cpp" } break; case 38: { Parser_Lel_longest_match_part *__ref0 = (Parser_Lel_longest_match_part*)&rhs[1]->user.longest_match_part; Parser_Lel_lm_part_list *__ref1 = (Parser_Lel_lm_part_list*)&rhs[0]->user.lm_part_list; Parser_Lel_longest_match_part *__ref2 = (Parser_Lel_longest_match_part*)&rhs[1]->user.longest_match_part; Parser_Lel_lm_part_list *__ref3 = (Parser_Lel_lm_part_list*)&redLel->user.lm_part_list; Parser_Lel_lm_part_list *__ref4 = (Parser_Lel_lm_part_list*)&rhs[0]->user.lm_part_list; #line 270 "rlparse.kl" if ( (__ref0)->lmPart != 0 ) (__ref1)->lmPartList->append( (__ref2)->lmPart ); (__ref3)->lmPartList = (__ref4)->lmPartList; #line 4322 "rlparse.cpp" } break; case 39: { Parser_Lel_lm_part_list *__ref0 = (Parser_Lel_lm_part_list*)&redLel->user.lm_part_list; Parser_Lel_longest_match_part *__ref1 = (Parser_Lel_longest_match_part*)&rhs[0]->user.longest_match_part; Parser_Lel_lm_part_list *__ref2 = (Parser_Lel_lm_part_list*)&redLel->user.lm_part_list; Parser_Lel_longest_match_part *__ref3 = (Parser_Lel_longest_match_part*)&rhs[0]->user.longest_match_part; #line 277 "rlparse.kl" /* Create a new list with the part. */ (__ref0)->lmPartList = new LmPartList; if ( (__ref1)->lmPart != 0 ) (__ref2)->lmPartList->append( (__ref3)->lmPart ); #line 4337 "rlparse.cpp" } break; case 40: { Parser_Lel_longest_match_part *__ref0 = (Parser_Lel_longest_match_part*)&redLel->user.longest_match_part; #line 290 "rlparse.kl" (__ref0)->lmPart = 0; #line 4344 "rlparse.cpp" } break; case 41: { Parser_Lel_longest_match_part *__ref0 = (Parser_Lel_longest_match_part*)&redLel->user.longest_match_part; #line 292 "rlparse.kl" (__ref0)->lmPart = 0; #line 4351 "rlparse.cpp" } break; case 42: { Parser_Lel_longest_match_part *__ref0 = (Parser_Lel_longest_match_part*)&redLel->user.longest_match_part; Parser_Lel_opt_lm_part_action *__ref1 = (Parser_Lel_opt_lm_part_action*)&rhs[1]->user.opt_lm_part_action; Parser_Lel_longest_match_part *__ref2 = (Parser_Lel_longest_match_part*)&redLel->user.longest_match_part; Parser_Lel_join *__ref3 = (Parser_Lel_join*)&rhs[0]->user.join; Token *__ref4 = (Token*)&rhs[2]->user.token; Parser_Lel_join *__ref5 = (Parser_Lel_join*)&rhs[0]->user.join; Token *__ref6 = (Token*)&rhs[2]->user.token; #line 294 "rlparse.kl" (__ref0)->lmPart = 0; Action *action = (__ref1)->action; if ( action != 0 ) action->isLmAction = true; (__ref2)->lmPart = new LongestMatchPart( (__ref3)->join, action, (__ref4)->loc, pd->nextLongestMatchId++ ); /* Provide a location to join. Unfortunately We don't * have the start of the join as in other occurances. Use the end. */ (__ref5)->join->loc = (__ref6)->loc; #line 4375 "rlparse.cpp" } break; case 43: { Parser_Lel_opt_lm_part_action *__ref0 = (Parser_Lel_opt_lm_part_action*)&redLel->user.opt_lm_part_action; Parser_Lel_action_ref *__ref1 = (Parser_Lel_action_ref*)&rhs[1]->user.action_ref; #line 313 "rlparse.kl" (__ref0)->action = (__ref1)->action; #line 4385 "rlparse.cpp" } break; case 44: { Parser_Lel_opt_lm_part_action *__ref0 = (Parser_Lel_opt_lm_part_action*)&redLel->user.opt_lm_part_action; Parser_Lel_action_ref *__ref1 = (Parser_Lel_action_ref*)&rhs[0]->user.action_ref; #line 317 "rlparse.kl" (__ref0)->action = (__ref1)->action; #line 4395 "rlparse.cpp" } break; case 45: { Parser_Lel_opt_lm_part_action *__ref0 = (Parser_Lel_opt_lm_part_action*)&redLel->user.opt_lm_part_action; #line 321 "rlparse.kl" (__ref0)->action = 0; #line 4404 "rlparse.cpp" } break; case 46: { Parser_Lel_join *__ref0 = (Parser_Lel_join*)&rhs[0]->user.join; Parser_Lel_expression *__ref1 = (Parser_Lel_expression*)&rhs[2]->user.expression; Parser_Lel_join *__ref2 = (Parser_Lel_join*)&redLel->user.join; Parser_Lel_join *__ref3 = (Parser_Lel_join*)&rhs[0]->user.join; #line 332 "rlparse.kl" /* Append the expression to the list and return it. */ (__ref0)->join->exprList.append( (__ref1)->expression ); (__ref2)->join = (__ref3)->join; #line 4418 "rlparse.cpp" } break; case 47: { Parser_Lel_join *__ref0 = (Parser_Lel_join*)&redLel->user.join; Parser_Lel_expression *__ref1 = (Parser_Lel_expression*)&rhs[0]->user.expression; #line 338 "rlparse.kl" (__ref0)->join = new Join( (__ref1)->expression ); #line 4428 "rlparse.cpp" } break; case 48: { Parser_Lel_expression *__ref0 = (Parser_Lel_expression*)&redLel->user.expression; Parser_Lel_expression *__ref1 = (Parser_Lel_expression*)&rhs[0]->user.expression; Parser_Lel_term_short *__ref2 = (Parser_Lel_term_short*)&rhs[2]->user.term_short; #line 348 "rlparse.kl" (__ref0)->expression = new Expression( (__ref1)->expression, (__ref2)->term, Expression::OrType ); #line 4440 "rlparse.cpp" } break; case 49: { Parser_Lel_expression *__ref0 = (Parser_Lel_expression*)&redLel->user.expression; Parser_Lel_expression *__ref1 = (Parser_Lel_expression*)&rhs[0]->user.expression; Parser_Lel_term_short *__ref2 = (Parser_Lel_term_short*)&rhs[2]->user.term_short; #line 353 "rlparse.kl" (__ref0)->expression = new Expression( (__ref1)->expression, (__ref2)->term, Expression::IntersectType ); #line 4452 "rlparse.cpp" } break; case 50: { Parser_Lel_expression *__ref0 = (Parser_Lel_expression*)&redLel->user.expression; Parser_Lel_expression *__ref1 = (Parser_Lel_expression*)&rhs[0]->user.expression; Parser_Lel_term_short *__ref2 = (Parser_Lel_term_short*)&rhs[2]->user.term_short; #line 358 "rlparse.kl" (__ref0)->expression = new Expression( (__ref1)->expression, (__ref2)->term, Expression::SubtractType ); #line 4464 "rlparse.cpp" } break; case 51: { Parser_Lel_expression *__ref0 = (Parser_Lel_expression*)&redLel->user.expression; Parser_Lel_expression *__ref1 = (Parser_Lel_expression*)&rhs[0]->user.expression; Parser_Lel_term_short *__ref2 = (Parser_Lel_term_short*)&rhs[2]->user.term_short; #line 363 "rlparse.kl" (__ref0)->expression = new Expression( (__ref1)->expression, (__ref2)->term, Expression::StrongSubtractType ); #line 4476 "rlparse.cpp" } break; case 52: { Parser_Lel_expression *__ref0 = (Parser_Lel_expression*)&redLel->user.expression; Parser_Lel_term_short *__ref1 = (Parser_Lel_term_short*)&rhs[0]->user.term_short; #line 368 "rlparse.kl" (__ref0)->expression = new Expression( (__ref1)->term ); #line 4486 "rlparse.cpp" } break; case 53: { Parser_Lel_term_short *__ref0 = (Parser_Lel_term_short*)&redLel->user.term_short; Parser_Lel_term *__ref1 = (Parser_Lel_term*)&rhs[0]->user.term; #line 389 "rlparse.kl" (__ref0)->term = (__ref1)->term; #line 4496 "rlparse.cpp" } break; case 54: { Parser_Lel_term *__ref0 = (Parser_Lel_term*)&redLel->user.term; Parser_Lel_term *__ref1 = (Parser_Lel_term*)&rhs[0]->user.term; Parser_Lel_factor_with_label *__ref2 = (Parser_Lel_factor_with_label*)&rhs[1]->user.factor_with_label; #line 399 "rlparse.kl" (__ref0)->term = new Term( (__ref1)->term, (__ref2)->factorWithAug ); #line 4507 "rlparse.cpp" } break; case 55: { Parser_Lel_term *__ref0 = (Parser_Lel_term*)&redLel->user.term; Parser_Lel_term *__ref1 = (Parser_Lel_term*)&rhs[0]->user.term; Parser_Lel_factor_with_label *__ref2 = (Parser_Lel_factor_with_label*)&rhs[2]->user.factor_with_label; #line 403 "rlparse.kl" (__ref0)->term = new Term( (__ref1)->term, (__ref2)->factorWithAug ); #line 4518 "rlparse.cpp" } break; case 56: { Parser_Lel_term *__ref0 = (Parser_Lel_term*)&redLel->user.term; Parser_Lel_term *__ref1 = (Parser_Lel_term*)&rhs[0]->user.term; Parser_Lel_factor_with_label *__ref2 = (Parser_Lel_factor_with_label*)&rhs[2]->user.factor_with_label; #line 407 "rlparse.kl" (__ref0)->term = new Term( (__ref1)->term, (__ref2)->factorWithAug, Term::RightStartType ); #line 4529 "rlparse.cpp" } break; case 57: { Parser_Lel_term *__ref0 = (Parser_Lel_term*)&redLel->user.term; Parser_Lel_term *__ref1 = (Parser_Lel_term*)&rhs[0]->user.term; Parser_Lel_factor_with_label *__ref2 = (Parser_Lel_factor_with_label*)&rhs[2]->user.factor_with_label; #line 411 "rlparse.kl" (__ref0)->term = new Term( (__ref1)->term, (__ref2)->factorWithAug, Term::RightFinishType ); #line 4540 "rlparse.cpp" } break; case 58: { Parser_Lel_term *__ref0 = (Parser_Lel_term*)&redLel->user.term; Parser_Lel_term *__ref1 = (Parser_Lel_term*)&rhs[0]->user.term; Parser_Lel_factor_with_label *__ref2 = (Parser_Lel_factor_with_label*)&rhs[2]->user.factor_with_label; #line 415 "rlparse.kl" (__ref0)->term = new Term( (__ref1)->term, (__ref2)->factorWithAug, Term::LeftType ); #line 4552 "rlparse.cpp" } break; case 59: { Parser_Lel_term *__ref0 = (Parser_Lel_term*)&redLel->user.term; Parser_Lel_factor_with_label *__ref1 = (Parser_Lel_factor_with_label*)&rhs[0]->user.factor_with_label; #line 420 "rlparse.kl" (__ref0)->term = new Term( (__ref1)->factorWithAug ); #line 4562 "rlparse.cpp" } break; case 60: { Parser_Lel_factor_with_label *__ref0 = (Parser_Lel_factor_with_label*)&rhs[2]->user.factor_with_label; Token *__ref1 = (Token*)&rhs[0]->user.token; Token *__ref2 = (Token*)&rhs[0]->user.token; Parser_Lel_factor_with_label *__ref3 = (Parser_Lel_factor_with_label*)&redLel->user.factor_with_label; Parser_Lel_factor_with_label *__ref4 = (Parser_Lel_factor_with_label*)&rhs[2]->user.factor_with_label; #line 430 "rlparse.kl" /* Add the label to the list and pass the factor up. */ (__ref0)->factorWithAug->labels.prepend( Label((__ref1)->loc, (__ref2)->data) ); (__ref3)->factorWithAug = (__ref4)->factorWithAug; #line 4577 "rlparse.cpp" } break; case 61: { Parser_Lel_factor_with_label *__ref0 = (Parser_Lel_factor_with_label*)&redLel->user.factor_with_label; Parser_Lel_factor_with_ep *__ref1 = (Parser_Lel_factor_with_ep*)&rhs[0]->user.factor_with_ep; #line 436 "rlparse.kl" (__ref0)->factorWithAug = (__ref1)->factorWithAug; #line 4587 "rlparse.cpp" } break; case 62: { Parser_Lel_factor_with_ep *__ref0 = (Parser_Lel_factor_with_ep*)&rhs[0]->user.factor_with_ep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_ep *__ref2 = (Parser_Lel_factor_with_ep*)&redLel->user.factor_with_ep; Parser_Lel_factor_with_ep *__ref3 = (Parser_Lel_factor_with_ep*)&rhs[0]->user.factor_with_ep; #line 446 "rlparse.kl" /* Add the target to the list and return the factor object. */ (__ref0)->factorWithAug->epsilonLinks.append( EpsilonLink( (__ref1)->loc, nameRef ) ); (__ref2)->factorWithAug = (__ref3)->factorWithAug; #line 4601 "rlparse.cpp" } break; case 63: { Parser_Lel_factor_with_ep *__ref0 = (Parser_Lel_factor_with_ep*)&redLel->user.factor_with_ep; Parser_Lel_factor_with_aug *__ref1 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 452 "rlparse.kl" (__ref0)->factorWithAug = (__ref1)->factorWithAug; #line 4611 "rlparse.cpp" } break; case 64: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 462 "rlparse.kl" /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, 0, (__ref3)->action ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4629 "rlparse.cpp" } break; case 65: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_priority_aug *__ref2 = (Parser_Lel_priority_aug*)&rhs[2]->user.priority_aug; Parser_Lel_factor_with_aug *__ref3 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 470 "rlparse.kl" /* Append the named priority to the factorWithAug and pass it up. */ (__ref0)->factorWithAug->priorityAugs.append( PriorityAug( (__ref1)->augType, pd->curDefPriorKey, (__ref2)->priorityNum ) ); (__ref3)->factorWithAug = (__ref4)->factorWithAug; #line 4645 "rlparse.cpp" } break; case 66: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_priority_name *__ref2 = (Parser_Lel_priority_name*)&rhs[3]->user.priority_name; Parser_Lel_priority_aug *__ref3 = (Parser_Lel_priority_aug*)&rhs[5]->user.priority_aug; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 477 "rlparse.kl" /* Append the priority using a default name. */ (__ref0)->factorWithAug->priorityAugs.append( PriorityAug( (__ref1)->augType, (__ref2)->priorityName, (__ref3)->priorityNum ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4662 "rlparse.cpp" } break; case 67: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 484 "rlparse.kl" (__ref0)->factorWithAug->conditions.append( ConditionTest( (__ref1)->loc, (__ref2)->augType, (__ref3)->action, true ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4678 "rlparse.cpp" } break; case 68: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[3]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 490 "rlparse.kl" (__ref0)->factorWithAug->conditions.append( ConditionTest( (__ref1)->loc, (__ref2)->augType, (__ref3)->action, false ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4694 "rlparse.cpp" } break; case 69: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 496 "rlparse.kl" /* Append the action, pass it up. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, 0, (__ref3)->action ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4711 "rlparse.cpp" } break; case 70: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 503 "rlparse.kl" /* Append the action, pass it up. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, 0, (__ref3)->action ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4728 "rlparse.cpp" } break; case 71: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 510 "rlparse.kl" /* Append the action, pass it up. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, 0, (__ref3)->action ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4745 "rlparse.cpp" } break; case 72: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 517 "rlparse.kl" /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, pd->curDefLocalErrKey, (__ref3)->action ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4763 "rlparse.cpp" } break; case 73: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_action_ref *__ref3 = (Parser_Lel_action_ref*)&rhs[2]->user.action_ref; Parser_Lel_factor_with_aug *__ref4 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 525 "rlparse.kl" /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, pd->curDefLocalErrKey, (__ref3)->action ) ); (__ref4)->factorWithAug = (__ref5)->factorWithAug; #line 4781 "rlparse.cpp" } break; case 74: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; Parser_Lel_aug_type *__ref1 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&rhs[1]->user.aug_type; Parser_Lel_local_err_name *__ref3 = (Parser_Lel_local_err_name*)&rhs[3]->user.local_err_name; Parser_Lel_action_ref *__ref4 = (Parser_Lel_action_ref*)&rhs[5]->user.action_ref; Parser_Lel_factor_with_aug *__ref5 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_aug *__ref6 = (Parser_Lel_factor_with_aug*)&rhs[0]->user.factor_with_aug; #line 533 "rlparse.kl" /* Append the action to the factorWithAug, record the refernce from * factorWithAug to the action and pass up the factorWithAug. */ (__ref0)->factorWithAug->actions.append( ParserAction( (__ref1)->loc, (__ref2)->augType, (__ref3)->error_name, (__ref4)->action ) ); (__ref5)->factorWithAug = (__ref6)->factorWithAug; #line 4800 "rlparse.cpp" } break; case 75: { Parser_Lel_factor_with_aug *__ref0 = (Parser_Lel_factor_with_aug*)&redLel->user.factor_with_aug; Parser_Lel_factor_with_rep *__ref1 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; #line 541 "rlparse.kl" (__ref0)->factorWithAug = new FactorWithAug( (__ref1)->factorWithRep ); #line 4810 "rlparse.cpp" } break; case 76: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 554 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_finish; #line 4819 "rlparse.cpp" } break; case 77: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 555 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_leave; #line 4828 "rlparse.cpp" } break; case 78: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 556 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all; #line 4837 "rlparse.cpp" } break; case 79: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 557 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start; #line 4846 "rlparse.cpp" } break; case 80: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 562 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start; #line 4855 "rlparse.cpp" } break; case 81: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 563 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start; #line 4864 "rlparse.cpp" } break; case 82: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 564 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all; #line 4873 "rlparse.cpp" } break; case 83: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 565 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all; #line 4882 "rlparse.cpp" } break; case 84: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 566 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_leave; #line 4891 "rlparse.cpp" } break; case 85: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 567 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_leave; #line 4900 "rlparse.cpp" } break; case 86: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 568 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all; #line 4909 "rlparse.cpp" } break; case 87: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 569 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start; #line 4918 "rlparse.cpp" } break; case 88: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 570 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_leave; #line 4927 "rlparse.cpp" } break; case 89: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 579 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_to_state; #line 4936 "rlparse.cpp" } break; case 90: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 581 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_to_state; #line 4945 "rlparse.cpp" } break; case 91: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 584 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_to_state; #line 4954 "rlparse.cpp" } break; case 92: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 586 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_to_state; #line 4963 "rlparse.cpp" } break; case 93: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 589 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_to_state; #line 4972 "rlparse.cpp" } break; case 94: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 591 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_to_state; #line 4981 "rlparse.cpp" } break; case 95: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 594 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_to_state; #line 4990 "rlparse.cpp" } break; case 96: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 596 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_to_state; #line 4999 "rlparse.cpp" } break; case 97: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 599 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_to_state; #line 5008 "rlparse.cpp" } break; case 98: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 601 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_to_state; #line 5017 "rlparse.cpp" } break; case 99: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 604 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_to_state; #line 5026 "rlparse.cpp" } break; case 100: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 606 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_to_state; #line 5035 "rlparse.cpp" } break; case 101: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 615 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_from_state; #line 5044 "rlparse.cpp" } break; case 102: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 617 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_from_state; #line 5053 "rlparse.cpp" } break; case 103: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 620 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_from_state; #line 5062 "rlparse.cpp" } break; case 104: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 622 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_from_state; #line 5071 "rlparse.cpp" } break; case 105: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 625 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_from_state; #line 5080 "rlparse.cpp" } break; case 106: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 627 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_from_state; #line 5089 "rlparse.cpp" } break; case 107: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 630 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_from_state; #line 5098 "rlparse.cpp" } break; case 108: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 632 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_from_state; #line 5107 "rlparse.cpp" } break; case 109: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 635 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_from_state; #line 5116 "rlparse.cpp" } break; case 110: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 637 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_from_state; #line 5125 "rlparse.cpp" } break; case 111: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 640 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_from_state; #line 5134 "rlparse.cpp" } break; case 112: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 642 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_from_state; #line 5143 "rlparse.cpp" } break; case 113: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 651 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_eof; #line 5152 "rlparse.cpp" } break; case 114: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 653 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_eof; #line 5161 "rlparse.cpp" } break; case 115: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 656 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_eof; #line 5170 "rlparse.cpp" } break; case 116: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 658 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_eof; #line 5179 "rlparse.cpp" } break; case 117: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 661 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_eof; #line 5188 "rlparse.cpp" } break; case 118: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 663 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_eof; #line 5197 "rlparse.cpp" } break; case 119: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 666 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_eof; #line 5206 "rlparse.cpp" } break; case 120: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 668 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_eof; #line 5215 "rlparse.cpp" } break; case 121: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 671 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_eof; #line 5224 "rlparse.cpp" } break; case 122: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 673 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_eof; #line 5233 "rlparse.cpp" } break; case 123: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 676 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_eof; #line 5242 "rlparse.cpp" } break; case 124: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 678 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_eof; #line 5251 "rlparse.cpp" } break; case 125: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 687 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_gbl_error; #line 5260 "rlparse.cpp" } break; case 126: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 689 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_gbl_error; #line 5269 "rlparse.cpp" } break; case 127: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 692 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_gbl_error; #line 5278 "rlparse.cpp" } break; case 128: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 694 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_gbl_error; #line 5287 "rlparse.cpp" } break; case 129: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 697 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_gbl_error; #line 5296 "rlparse.cpp" } break; case 130: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 699 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_gbl_error; #line 5305 "rlparse.cpp" } break; case 131: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 702 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_gbl_error; #line 5314 "rlparse.cpp" } break; case 132: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 704 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_gbl_error; #line 5323 "rlparse.cpp" } break; case 133: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 707 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_gbl_error; #line 5332 "rlparse.cpp" } break; case 134: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 709 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_gbl_error; #line 5341 "rlparse.cpp" } break; case 135: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 712 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_gbl_error; #line 5350 "rlparse.cpp" } break; case 136: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 714 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_gbl_error; #line 5359 "rlparse.cpp" } break; case 137: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 724 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_local_error; #line 5368 "rlparse.cpp" } break; case 138: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 726 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_start_local_error; #line 5377 "rlparse.cpp" } break; case 139: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 729 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_local_error; #line 5386 "rlparse.cpp" } break; case 140: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 731 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_start_local_error; #line 5395 "rlparse.cpp" } break; case 141: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 734 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_local_error; #line 5404 "rlparse.cpp" } break; case 142: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 736 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_all_local_error; #line 5413 "rlparse.cpp" } break; case 143: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 739 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_local_error; #line 5422 "rlparse.cpp" } break; case 144: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 741 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_final_local_error; #line 5431 "rlparse.cpp" } break; case 145: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 744 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_local_error; #line 5440 "rlparse.cpp" } break; case 146: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 746 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_not_final_local_error; #line 5449 "rlparse.cpp" } break; case 147: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 749 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_local_error; #line 5458 "rlparse.cpp" } break; case 148: { Parser_Lel_aug_type *__ref0 = (Parser_Lel_aug_type*)&redLel->user.aug_type; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_aug_type *__ref2 = (Parser_Lel_aug_type*)&redLel->user.aug_type; #line 751 "rlparse.kl" (__ref0)->loc = (__ref1)->loc; (__ref2)->augType = at_middle_local_error; #line 5467 "rlparse.cpp" } break; case 149: { Parser_Lel_action_ref *__ref0 = (Parser_Lel_action_ref*)&redLel->user.action_ref; Parser_Lel_action_ref *__ref1 = (Parser_Lel_action_ref*)&rhs[0]->user.action_ref; #line 764 "rlparse.kl" (__ref0)->action = (__ref1)->action; #line 5475 "rlparse.cpp" } break; case 150: { Parser_Lel_action_ref *__ref0 = (Parser_Lel_action_ref*)&redLel->user.action_ref; Parser_Lel_action_ref *__ref1 = (Parser_Lel_action_ref*)&rhs[1]->user.action_ref; #line 765 "rlparse.kl" (__ref0)->action = (__ref1)->action; #line 5483 "rlparse.cpp" } break; case 151: { Parser_Lel_action_ref *__ref0 = (Parser_Lel_action_ref*)&redLel->user.action_ref; Parser_Lel_action_ref *__ref1 = (Parser_Lel_action_ref*)&rhs[0]->user.action_ref; #line 766 "rlparse.kl" (__ref0)->action = (__ref1)->action; #line 5491 "rlparse.cpp" } break; case 152: { Token *__ref0 = (Token*)&rhs[0]->user.token; Parser_Lel_action_ref *__ref1 = (Parser_Lel_action_ref*)&redLel->user.action_ref; Token *__ref2 = (Token*)&rhs[0]->user.token; Token *__ref3 = (Token*)&rhs[0]->user.token; Parser_Lel_action_ref *__ref4 = (Parser_Lel_action_ref*)&redLel->user.action_ref; #line 771 "rlparse.kl" /* Set the name in the actionDict. */ Action *action = pd->actionDict.find( (__ref0)->data ); if ( action != 0 ) { /* Pass up the action element */ (__ref1)->action = action; } else { /* Will recover by returning null as the action. */ error((__ref2)->loc) << "action lookup of \"" << (__ref3)->data << "\" failed" << endl; (__ref4)->action = 0; } #line 5514 "rlparse.cpp" } break; case 153: { Token *__ref0 = (Token*)&rhs[0]->user.token; Parser_Lel_inline_list *__ref1 = (Parser_Lel_inline_list*)&rhs[1]->user.inline_list; Parser_Lel_action_ref *__ref2 = (Parser_Lel_action_ref*)&redLel->user.action_ref; #line 788 "rlparse.kl" /* Create the action, add it to the list and pass up. */ Action *newAction = new Action( (__ref0)->loc, 0, (__ref1)->inlineList, pd->nextCondId++ ); pd->actionList.append( newAction ); (__ref2)->action = newAction; #line 5528 "rlparse.cpp" } break; case 154: { Token *__ref0 = (Token*)&rhs[0]->user.token; Parser_Lel_priority_name *__ref1 = (Parser_Lel_priority_name*)&redLel->user.priority_name; #line 803 "rlparse.kl" // Lookup/create the priority key. PriorDictEl *priorDictEl; if ( pd->priorDict.insert( (__ref0)->data, pd->nextPriorKey, &priorDictEl ) ) pd->nextPriorKey += 1; // Use the inserted/found priority key. (__ref1)->priorityName = priorDictEl->value; #line 5544 "rlparse.cpp" } break; case 155: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_priority_aug *__ref3 = (Parser_Lel_priority_aug*)&redLel->user.priority_aug; Parser_Lel_token_type *__ref4 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref5 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_priority_aug *__ref6 = (Parser_Lel_priority_aug*)&redLel->user.priority_aug; Parser_Lel_priority_aug *__ref7 = (Parser_Lel_priority_aug*)&redLel->user.priority_aug; #line 820 "rlparse.kl" // Convert the priority number to a long. Check for overflow. errno = 0; //cerr << "PRIOR AUG: " << $1->token.data << endl; long aug = strtol( (__ref0)->token.data, 0, 10 ); if ( errno == ERANGE && aug == LONG_MAX ) { /* Priority number too large. Recover by setting the priority to 0. */ error((__ref1)->token.loc) << "priority number " << (__ref2)->token.data << " overflows" << endl; (__ref3)->priorityNum = 0; } else if ( errno == ERANGE && aug == LONG_MIN ) { /* Priority number too large in the neg. Recover by using 0. */ error((__ref4)->token.loc) << "priority number " << (__ref5)->token.data << " underflows" << endl; (__ref6)->priorityNum = 0; } else { /* No overflow or underflow. */ (__ref7)->priorityNum = aug; } #line 5579 "rlparse.cpp" } break; case 156: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 846 "rlparse.kl" (__ref0)->token = *(__ref1); #line 5589 "rlparse.cpp" } break; case 157: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref2 = (Token*)&rhs[0]->user.token; Parser_Lel_token_type *__ref3 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref4 = (Token*)&rhs[1]->user.token; #line 850 "rlparse.kl" (__ref0)->token.set( "+", 1 ); (__ref1)->token.loc = (__ref2)->loc; (__ref3)->token.append( *(__ref4) ); #line 5604 "rlparse.cpp" } break; case 158: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref2 = (Token*)&rhs[0]->user.token; Parser_Lel_token_type *__ref3 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref4 = (Token*)&rhs[1]->user.token; #line 856 "rlparse.kl" (__ref0)->token.set( "-", 1 ); (__ref1)->token.loc = (__ref2)->loc; (__ref3)->token.append( *(__ref4) ); #line 5619 "rlparse.cpp" } break; case 159: { Token *__ref0 = (Token*)&rhs[0]->user.token; Parser_Lel_local_err_name *__ref1 = (Parser_Lel_local_err_name*)&redLel->user.local_err_name; #line 868 "rlparse.kl" /* Lookup/create the priority key. */ LocalErrDictEl *localErrDictEl; if ( pd->localErrDict.insert( (__ref0)->data, pd->nextLocalErrKey, &localErrDictEl ) ) pd->nextLocalErrKey += 1; /* Use the inserted/found priority key. */ (__ref1)->error_name = localErrDictEl->value; #line 5635 "rlparse.cpp" } break; case 160: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; #line 889 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, 0, 0, FactorWithRep::StarType ); #line 5647 "rlparse.cpp" } break; case 161: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; #line 894 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, 0, 0, FactorWithRep::StarStarType ); #line 5659 "rlparse.cpp" } break; case 162: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; #line 899 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, 0, 0, FactorWithRep::OptionalType ); #line 5671 "rlparse.cpp" } break; case 163: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; #line 904 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, 0, 0, FactorWithRep::PlusType ); #line 5683 "rlparse.cpp" } break; case 164: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; Parser_Lel_factor_rep_num *__ref3 = (Parser_Lel_factor_rep_num*)&rhs[2]->user.factor_rep_num; #line 909 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, (__ref3)->rep, 0, FactorWithRep::ExactType ); #line 5696 "rlparse.cpp" } break; case 165: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; Parser_Lel_factor_rep_num *__ref3 = (Parser_Lel_factor_rep_num*)&rhs[3]->user.factor_rep_num; #line 914 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, 0, (__ref3)->rep, FactorWithRep::MaxType ); #line 5709 "rlparse.cpp" } break; case 166: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; Parser_Lel_factor_rep_num *__ref3 = (Parser_Lel_factor_rep_num*)&rhs[2]->user.factor_rep_num; #line 919 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, (__ref3)->rep, 0, FactorWithRep::MinType ); #line 5722 "rlparse.cpp" } break; case 167: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Token *__ref1 = (Token*)&rhs[1]->user.token; Parser_Lel_factor_with_rep *__ref2 = (Parser_Lel_factor_with_rep*)&rhs[0]->user.factor_with_rep; Parser_Lel_factor_rep_num *__ref3 = (Parser_Lel_factor_rep_num*)&rhs[2]->user.factor_rep_num; Parser_Lel_factor_rep_num *__ref4 = (Parser_Lel_factor_rep_num*)&rhs[4]->user.factor_rep_num; #line 924 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->loc, (__ref2)->factorWithRep, (__ref3)->rep, (__ref4)->rep, FactorWithRep::RangeType ); #line 5736 "rlparse.cpp" } break; case 168: { Parser_Lel_factor_with_rep *__ref0 = (Parser_Lel_factor_with_rep*)&redLel->user.factor_with_rep; Parser_Lel_factor_with_neg *__ref1 = (Parser_Lel_factor_with_neg*)&rhs[0]->user.factor_with_neg; #line 929 "rlparse.kl" (__ref0)->factorWithRep = new FactorWithRep( (__ref1)->factorWithNeg ); #line 5746 "rlparse.cpp" } break; case 169: { Token *__ref0 = (Token*)&rhs[0]->user.token; Token *__ref1 = (Token*)&rhs[0]->user.token; Token *__ref2 = (Token*)&rhs[0]->user.token; Parser_Lel_factor_rep_num *__ref3 = (Parser_Lel_factor_rep_num*)&redLel->user.factor_rep_num; Parser_Lel_factor_rep_num *__ref4 = (Parser_Lel_factor_rep_num*)&redLel->user.factor_rep_num; #line 939 "rlparse.kl" // Convert the priority number to a long. Check for overflow. errno = 0; long rep = strtol( (__ref0)->data, 0, 10 ); if ( errno == ERANGE && rep == LONG_MAX ) { // Repetition too large. Recover by returing repetition 1. */ error((__ref1)->loc) << "repetition number " << (__ref2)->data << " overflows" << endl; (__ref3)->rep = 1; } else { // Cannot be negative, so no overflow. (__ref4)->rep = rep; } #line 5770 "rlparse.cpp" } break; case 170: { Parser_Lel_factor_with_neg *__ref0 = (Parser_Lel_factor_with_neg*)&redLel->user.factor_with_neg; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_factor_with_neg *__ref2 = (Parser_Lel_factor_with_neg*)&rhs[1]->user.factor_with_neg; #line 965 "rlparse.kl" (__ref0)->factorWithNeg = new FactorWithNeg( (__ref1)->loc, (__ref2)->factorWithNeg, FactorWithNeg::NegateType ); #line 5782 "rlparse.cpp" } break; case 171: { Parser_Lel_factor_with_neg *__ref0 = (Parser_Lel_factor_with_neg*)&redLel->user.factor_with_neg; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_factor_with_neg *__ref2 = (Parser_Lel_factor_with_neg*)&rhs[1]->user.factor_with_neg; #line 970 "rlparse.kl" (__ref0)->factorWithNeg = new FactorWithNeg( (__ref1)->loc, (__ref2)->factorWithNeg, FactorWithNeg::CharNegateType ); #line 5794 "rlparse.cpp" } break; case 172: { Parser_Lel_factor_with_neg *__ref0 = (Parser_Lel_factor_with_neg*)&redLel->user.factor_with_neg; Parser_Lel_factor *__ref1 = (Parser_Lel_factor*)&rhs[0]->user.factor; #line 975 "rlparse.kl" (__ref0)->factorWithNeg = new FactorWithNeg( (__ref1)->factor ); #line 5804 "rlparse.cpp" } break; case 173: { Parser_Lel_factor *__ref0 = (Parser_Lel_factor*)&redLel->user.factor; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 985 "rlparse.kl" /* Create a new factor node going to a concat literal. */ (__ref0)->factor = new Factor( new Literal( *(__ref1), Literal::LitString ) ); #line 5815 "rlparse.cpp" } break; case 174: { Parser_Lel_factor *__ref0 = (Parser_Lel_factor*)&redLel->user.factor; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; #line 990 "rlparse.kl" /* Create a new factor node going to a literal number. */ (__ref0)->factor = new Factor( new Literal( (__ref1)->token, Literal::Number ) ); #line 5826 "rlparse.cpp" } break; case 175: { Token *__ref0 = (Token*)&rhs[0]->user.token; Token *__ref1 = (Token*)&rhs[0]->user.token; Token *__ref2 = (Token*)&rhs[0]->user.token; Parser_Lel_factor *__ref3 = (Parser_Lel_factor*)&redLel->user.factor; Token *__ref4 = (Token*)&rhs[0]->user.token; Parser_Lel_factor *__ref5 = (Parser_Lel_factor*)&redLel->user.factor; Parser_Lel_factor *__ref6 = (Parser_Lel_factor*)&redLel->user.factor; Token *__ref7 = (Token*)&rhs[0]->user.token; #line 995 "rlparse.kl" /* Find the named graph. */ GraphDictEl *gdNode = pd->graphDict.find( (__ref0)->data ); if ( gdNode == 0 ) { /* Recover by returning null as the factor node. */ error((__ref1)->loc) << "graph lookup of \"" << (__ref2)->data << "\" failed" << endl; (__ref3)->factor = 0; } else if ( gdNode->isInstance ) { /* Recover by retuning null as the factor node. */ error((__ref4)->loc) << "references to graph instantiations not allowed " "in expressions" << endl; (__ref5)->factor = 0; } else { /* Create a factor node that is a lookup of an expression. */ (__ref6)->factor = new Factor( (__ref7)->loc, gdNode->value ); } #line 5858 "rlparse.cpp" } break; case 176: { Parser_Lel_factor *__ref0 = (Parser_Lel_factor*)&redLel->user.factor; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_regular_expr_or_data *__ref2 = (Parser_Lel_regular_expr_or_data*)&rhs[1]->user.regular_expr_or_data; #line 1015 "rlparse.kl" /* Create a new factor node going to an OR expression. */ (__ref0)->factor = new Factor( new ReItem( (__ref1)->loc, (__ref2)->reOrBlock, ReItem::OrBlock ) ); #line 5870 "rlparse.cpp" } break; case 177: { Parser_Lel_factor *__ref0 = (Parser_Lel_factor*)&redLel->user.factor; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_regular_expr_or_data *__ref2 = (Parser_Lel_regular_expr_or_data*)&rhs[1]->user.regular_expr_or_data; #line 1020 "rlparse.kl" /* Create a new factor node going to a negated OR expression. */ (__ref0)->factor = new Factor( new ReItem( (__ref1)->loc, (__ref2)->reOrBlock, ReItem::NegOrBlock ) ); #line 5882 "rlparse.cpp" } break; case 178: { Token *__ref0 = (Token*)&rhs[2]->user.token; Token *__ref1 = (Token*)&rhs[2]->user.token; Parser_Lel_regular_expr *__ref2 = (Parser_Lel_regular_expr*)&rhs[1]->user.regular_expr; Parser_Lel_factor *__ref3 = (Parser_Lel_factor*)&redLel->user.factor; Parser_Lel_regular_expr *__ref4 = (Parser_Lel_regular_expr*)&rhs[1]->user.regular_expr; #line 1025 "rlparse.kl" if ( (__ref0)->length > 1 ) { for ( char *p = (__ref1)->data; *p != 0; p++ ) { if ( *p == 'i' ) (__ref2)->regExpr->caseInsensitive = true; } } /* Create a new factor node going to a regular exp. */ (__ref3)->factor = new Factor( (__ref4)->regExpr ); #line 5903 "rlparse.cpp" } break; case 179: { Parser_Lel_factor *__ref0 = (Parser_Lel_factor*)&redLel->user.factor; Parser_Lel_range_lit *__ref1 = (Parser_Lel_range_lit*)&rhs[0]->user.range_lit; Parser_Lel_range_lit *__ref2 = (Parser_Lel_range_lit*)&rhs[2]->user.range_lit; #line 1037 "rlparse.kl" /* Create a new factor node going to a range. */ (__ref0)->factor = new Factor( new Range( (__ref1)->literal, (__ref2)->literal ) ); #line 5915 "rlparse.cpp" } break; case 180: { Parser_Lel_factor *__ref0 = (Parser_Lel_factor*)&redLel->user.factor; Parser_Lel_join *__ref1 = (Parser_Lel_join*)&rhs[1]->user.join; Parser_Lel_join *__ref2 = (Parser_Lel_join*)&rhs[1]->user.join; Token *__ref3 = (Token*)&rhs[0]->user.token; #line 1042 "rlparse.kl" /* Create a new factor going to a parenthesized join. */ (__ref0)->factor = new Factor( (__ref1)->join ); (__ref2)->join->loc = (__ref3)->loc; #line 5929 "rlparse.cpp" } break; case 181: { Parser_Lel_range_lit *__ref0 = (Parser_Lel_range_lit*)&redLel->user.range_lit; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1055 "rlparse.kl" /* Range literas must have only one char. We restrict this in the parse tree. */ (__ref0)->literal = new Literal( *(__ref1), Literal::LitString ); #line 5940 "rlparse.cpp" } break; case 182: { Parser_Lel_range_lit *__ref0 = (Parser_Lel_range_lit*)&redLel->user.range_lit; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; #line 1060 "rlparse.kl" /* Create a new literal number. */ (__ref0)->literal = new Literal( (__ref1)->token, Literal::Number ); #line 5951 "rlparse.cpp" } break; case 183: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1069 "rlparse.kl" (__ref0)->token = *(__ref1); #line 5961 "rlparse.cpp" } break; case 184: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref2 = (Token*)&rhs[0]->user.token; Parser_Lel_token_type *__ref3 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref4 = (Token*)&rhs[1]->user.token; #line 1073 "rlparse.kl" (__ref0)->token.set( "-", 1 ); (__ref1)->token.loc = (__ref2)->loc; (__ref3)->token.append( *(__ref4) ); #line 5976 "rlparse.cpp" } break; case 185: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1079 "rlparse.kl" (__ref0)->token = *(__ref1); #line 5986 "rlparse.cpp" } break; case 186: { Parser_Lel_regular_expr_item *__ref0 = (Parser_Lel_regular_expr_item*)&rhs[1]->user.regular_expr_item; Parser_Lel_regular_expr_item *__ref1 = (Parser_Lel_regular_expr_item*)&rhs[1]->user.regular_expr_item; Parser_Lel_regular_expr *__ref2 = (Parser_Lel_regular_expr*)&rhs[0]->user.regular_expr; Parser_Lel_regular_expr *__ref3 = (Parser_Lel_regular_expr*)&rhs[0]->user.regular_expr; Parser_Lel_regular_expr *__ref4 = (Parser_Lel_regular_expr*)&rhs[0]->user.regular_expr; Parser_Lel_regular_expr *__ref5 = (Parser_Lel_regular_expr*)&rhs[0]->user.regular_expr; Parser_Lel_regular_expr_item *__ref6 = (Parser_Lel_regular_expr_item*)&rhs[1]->user.regular_expr_item; Parser_Lel_regular_expr_item *__ref7 = (Parser_Lel_regular_expr_item*)&rhs[1]->user.regular_expr_item; Parser_Lel_regular_expr *__ref8 = (Parser_Lel_regular_expr*)&redLel->user.regular_expr; Parser_Lel_regular_expr *__ref9 = (Parser_Lel_regular_expr*)&rhs[0]->user.regular_expr; Parser_Lel_regular_expr *__ref10 = (Parser_Lel_regular_expr*)&redLel->user.regular_expr; Parser_Lel_regular_expr *__ref11 = (Parser_Lel_regular_expr*)&rhs[0]->user.regular_expr; Parser_Lel_regular_expr_item *__ref12 = (Parser_Lel_regular_expr_item*)&rhs[1]->user.regular_expr_item; #line 1094 "rlparse.kl" /* An optimization to lessen the tree size. If a non-starred char is * directly under the left side on the right and the right side is * another non-starred char then paste them together and return the * left side. Otherwise just put the two under a new reg exp node. */ if ( (__ref0)->reItem->type == ReItem::Data && !(__ref1)->reItem->star && (__ref2)->regExpr->type == RegExpr::RecurseItem && (__ref3)->regExpr->item->type == ReItem::Data && !(__ref4)->regExpr->item->star ) { /* Append the right side to the right side of the left and toss the * right side. */ (__ref5)->regExpr->item->token.append( (__ref6)->reItem->token ); delete (__ref7)->reItem; (__ref8)->regExpr = (__ref9)->regExpr; } else { (__ref10)->regExpr = new RegExpr( (__ref11)->regExpr, (__ref12)->reItem ); } #line 6023 "rlparse.cpp" } break; case 187: { Parser_Lel_regular_expr *__ref0 = (Parser_Lel_regular_expr*)&redLel->user.regular_expr; #line 1114 "rlparse.kl" /* Can't optimize the tree. */ (__ref0)->regExpr = new RegExpr(); #line 6033 "rlparse.cpp" } break; case 188: { Parser_Lel_regular_expr_char *__ref0 = (Parser_Lel_regular_expr_char*)&rhs[0]->user.regular_expr_char; Parser_Lel_regular_expr_item *__ref1 = (Parser_Lel_regular_expr_item*)&redLel->user.regular_expr_item; Parser_Lel_regular_expr_char *__ref2 = (Parser_Lel_regular_expr_char*)&rhs[0]->user.regular_expr_char; #line 1126 "rlparse.kl" (__ref0)->reItem->star = true; (__ref1)->reItem = (__ref2)->reItem; #line 6045 "rlparse.cpp" } break; case 189: { Parser_Lel_regular_expr_item *__ref0 = (Parser_Lel_regular_expr_item*)&redLel->user.regular_expr_item; Parser_Lel_regular_expr_char *__ref1 = (Parser_Lel_regular_expr_char*)&rhs[0]->user.regular_expr_char; #line 1131 "rlparse.kl" (__ref0)->reItem = (__ref1)->reItem; #line 6055 "rlparse.cpp" } break; case 190: { Parser_Lel_regular_expr_char *__ref0 = (Parser_Lel_regular_expr_char*)&redLel->user.regular_expr_char; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_regular_expr_or_data *__ref2 = (Parser_Lel_regular_expr_or_data*)&rhs[1]->user.regular_expr_or_data; #line 1143 "rlparse.kl" (__ref0)->reItem = new ReItem( (__ref1)->loc, (__ref2)->reOrBlock, ReItem::OrBlock ); #line 6066 "rlparse.cpp" } break; case 191: { Parser_Lel_regular_expr_char *__ref0 = (Parser_Lel_regular_expr_char*)&redLel->user.regular_expr_char; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_regular_expr_or_data *__ref2 = (Parser_Lel_regular_expr_or_data*)&rhs[1]->user.regular_expr_or_data; #line 1147 "rlparse.kl" (__ref0)->reItem = new ReItem( (__ref1)->loc, (__ref2)->reOrBlock, ReItem::NegOrBlock ); #line 6077 "rlparse.cpp" } break; case 192: { Parser_Lel_regular_expr_char *__ref0 = (Parser_Lel_regular_expr_char*)&redLel->user.regular_expr_char; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1151 "rlparse.kl" (__ref0)->reItem = new ReItem( (__ref1)->loc, ReItem::Dot ); #line 6087 "rlparse.cpp" } break; case 193: { Parser_Lel_regular_expr_char *__ref0 = (Parser_Lel_regular_expr_char*)&redLel->user.regular_expr_char; Token *__ref1 = (Token*)&rhs[0]->user.token; Token *__ref2 = (Token*)&rhs[0]->user.token; #line 1155 "rlparse.kl" (__ref0)->reItem = new ReItem( (__ref1)->loc, *(__ref2) ); #line 6098 "rlparse.cpp" } break; case 194: { Parser_Lel_regular_expr_or_char *__ref0 = (Parser_Lel_regular_expr_or_char*)&rhs[1]->user.regular_expr_or_char; Parser_Lel_regular_expr_or_data *__ref1 = (Parser_Lel_regular_expr_or_data*)&rhs[0]->user.regular_expr_or_data; Parser_Lel_regular_expr_or_data *__ref2 = (Parser_Lel_regular_expr_or_data*)&rhs[0]->user.regular_expr_or_data; Parser_Lel_regular_expr_or_data *__ref3 = (Parser_Lel_regular_expr_or_data*)&rhs[0]->user.regular_expr_or_data; Parser_Lel_regular_expr_or_char *__ref4 = (Parser_Lel_regular_expr_or_char*)&rhs[1]->user.regular_expr_or_char; Parser_Lel_regular_expr_or_char *__ref5 = (Parser_Lel_regular_expr_or_char*)&rhs[1]->user.regular_expr_or_char; Parser_Lel_regular_expr_or_data *__ref6 = (Parser_Lel_regular_expr_or_data*)&redLel->user.regular_expr_or_data; Parser_Lel_regular_expr_or_data *__ref7 = (Parser_Lel_regular_expr_or_data*)&rhs[0]->user.regular_expr_or_data; Parser_Lel_regular_expr_or_data *__ref8 = (Parser_Lel_regular_expr_or_data*)&redLel->user.regular_expr_or_data; Parser_Lel_regular_expr_or_data *__ref9 = (Parser_Lel_regular_expr_or_data*)&rhs[0]->user.regular_expr_or_data; Parser_Lel_regular_expr_or_char *__ref10 = (Parser_Lel_regular_expr_or_char*)&rhs[1]->user.regular_expr_or_char; #line 1167 "rlparse.kl" /* An optimization to lessen the tree size. If an or char is directly * under the left side on the right and the right side is another or * char then paste them together and return the left side. Otherwise * just put the two under a new or data node. */ if ( (__ref0)->reOrItem->type == ReOrItem::Data && (__ref1)->reOrBlock->type == ReOrBlock::RecurseItem && (__ref2)->reOrBlock->item->type == ReOrItem::Data ) { /* Append the right side to right side of the left and toss the * right side. */ (__ref3)->reOrBlock->item->token.append( (__ref4)->reOrItem->token ); delete (__ref5)->reOrItem; (__ref6)->reOrBlock = (__ref7)->reOrBlock; } else { /* Can't optimize, put the left and right under a new node. */ (__ref8)->reOrBlock = new ReOrBlock( (__ref9)->reOrBlock, (__ref10)->reOrItem ); } #line 6134 "rlparse.cpp" } break; case 195: { Parser_Lel_regular_expr_or_data *__ref0 = (Parser_Lel_regular_expr_or_data*)&redLel->user.regular_expr_or_data; #line 1188 "rlparse.kl" (__ref0)->reOrBlock = new ReOrBlock(); #line 6143 "rlparse.cpp" } break; case 196: { Parser_Lel_regular_expr_or_char *__ref0 = (Parser_Lel_regular_expr_or_char*)&redLel->user.regular_expr_or_char; Token *__ref1 = (Token*)&rhs[0]->user.token; Token *__ref2 = (Token*)&rhs[0]->user.token; #line 1200 "rlparse.kl" (__ref0)->reOrItem = new ReOrItem( (__ref1)->loc, *(__ref2) ); #line 6154 "rlparse.cpp" } break; case 197: { Parser_Lel_regular_expr_or_char *__ref0 = (Parser_Lel_regular_expr_or_char*)&redLel->user.regular_expr_or_char; Token *__ref1 = (Token*)&rhs[1]->user.token; Token *__ref2 = (Token*)&rhs[0]->user.token; Token *__ref3 = (Token*)&rhs[2]->user.token; #line 1204 "rlparse.kl" (__ref0)->reOrItem = new ReOrItem( (__ref1)->loc, (__ref2)->data[0], (__ref3)->data[0] ); #line 6166 "rlparse.cpp" } break; case 198: { Parser_Lel_inline_list *__ref0 = (Parser_Lel_inline_list*)&redLel->user.inline_list; Parser_Lel_inline_list *__ref1 = (Parser_Lel_inline_list*)&rhs[0]->user.inline_list; Parser_Lel_inline_list *__ref2 = (Parser_Lel_inline_list*)&redLel->user.inline_list; Parser_Lel_inline_item *__ref3 = (Parser_Lel_inline_item*)&rhs[1]->user.inline_item; #line 1221 "rlparse.kl" /* Append the item to the list, return the list. */ (__ref0)->inlineList = (__ref1)->inlineList; (__ref2)->inlineList->append( (__ref3)->inlineItem ); #line 6180 "rlparse.cpp" } break; case 199: { Parser_Lel_inline_list *__ref0 = (Parser_Lel_inline_list*)&redLel->user.inline_list; #line 1228 "rlparse.kl" /* Start with empty list. */ (__ref0)->inlineList = new InlineList; #line 6190 "rlparse.cpp" } break; case 200: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; #line 1243 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->token.loc, (__ref2)->token.data, InlineItem::Text ); #line 6201 "rlparse.cpp" } break; case 201: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; #line 1249 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->token.loc, (__ref2)->token.data, InlineItem::Text ); #line 6212 "rlparse.cpp" } break; case 202: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_item *__ref1 = (Parser_Lel_inline_item*)&rhs[0]->user.inline_item; #line 1255 "rlparse.kl" /* Pass the inline item up. */ (__ref0)->inlineItem = (__ref1)->inlineItem; #line 6223 "rlparse.cpp" } break; case 203: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1262 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6231 "rlparse.cpp" } break; case 204: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1263 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6239 "rlparse.cpp" } break; case 205: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1264 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6247 "rlparse.cpp" } break; case 206: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1265 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6255 "rlparse.cpp" } break; case 207: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1266 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6263 "rlparse.cpp" } break; case 208: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1267 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6271 "rlparse.cpp" } break; case 209: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_item *__ref1 = (Parser_Lel_inline_item*)&rhs[0]->user.inline_item; #line 1271 "rlparse.kl" /* Pass up interpreted items of inline expressions. */ (__ref0)->inlineItem = (__ref1)->inlineItem; #line 6282 "rlparse.cpp" } break; case 210: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1276 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Hold ); #line 6292 "rlparse.cpp" } break; case 211: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_inline_item *__ref2 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_list *__ref3 = (Parser_Lel_inline_list*)&rhs[1]->user.inline_list; #line 1280 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Exec ); (__ref2)->inlineItem->children = (__ref3)->inlineList; #line 6305 "rlparse.cpp" } break; case 212: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1285 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, new NameRef(nameRef), InlineItem::Goto ); #line 6316 "rlparse.cpp" } break; case 213: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_inline_item *__ref2 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_list *__ref3 = (Parser_Lel_inline_list*)&rhs[2]->user.inline_list; #line 1290 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::GotoExpr ); (__ref2)->inlineItem->children = (__ref3)->inlineList; #line 6329 "rlparse.cpp" } break; case 214: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1295 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, new NameRef(nameRef), InlineItem::Next ); #line 6339 "rlparse.cpp" } break; case 215: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_inline_item *__ref2 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_list *__ref3 = (Parser_Lel_inline_list*)&rhs[2]->user.inline_list; #line 1299 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::NextExpr ); (__ref2)->inlineItem->children = (__ref3)->inlineList; #line 6352 "rlparse.cpp" } break; case 216: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1304 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, new NameRef(nameRef), InlineItem::Call ); #line 6362 "rlparse.cpp" } break; case 217: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; Parser_Lel_inline_item *__ref2 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_list *__ref3 = (Parser_Lel_inline_list*)&rhs[2]->user.inline_list; #line 1308 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::CallExpr ); (__ref2)->inlineItem->children = (__ref3)->inlineList; #line 6375 "rlparse.cpp" } break; case 218: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1313 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Ret ); #line 6385 "rlparse.cpp" } break; case 219: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1317 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Break ); #line 6395 "rlparse.cpp" } break; case 220: { Parser_Lel_inline_list *__ref0 = (Parser_Lel_inline_list*)&redLel->user.inline_list; Parser_Lel_inline_list *__ref1 = (Parser_Lel_inline_list*)&rhs[0]->user.inline_list; Parser_Lel_inline_list *__ref2 = (Parser_Lel_inline_list*)&redLel->user.inline_list; Parser_Lel_inline_item *__ref3 = (Parser_Lel_inline_item*)&rhs[1]->user.inline_item; #line 1325 "rlparse.kl" (__ref0)->inlineList = (__ref1)->inlineList; (__ref2)->inlineList->append( (__ref3)->inlineItem ); #line 6408 "rlparse.cpp" } break; case 221: { Parser_Lel_inline_list *__ref0 = (Parser_Lel_inline_list*)&redLel->user.inline_list; #line 1330 "rlparse.kl" /* Init the list used for this expr. */ (__ref0)->inlineList = new InlineList; #line 6418 "rlparse.cpp" } break; case 222: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; #line 1339 "rlparse.kl" /* Return a text segment. */ (__ref0)->inlineItem = new InlineItem( (__ref1)->token.loc, (__ref2)->token.data, InlineItem::Text ); #line 6430 "rlparse.cpp" } break; case 223: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_token_type *__ref1 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; Parser_Lel_token_type *__ref2 = (Parser_Lel_token_type*)&rhs[0]->user.token_type; #line 1345 "rlparse.kl" /* Return a text segment, must heap alloc the text. */ (__ref0)->inlineItem = new InlineItem( (__ref1)->token.loc, (__ref2)->token.data, InlineItem::Text ); #line 6442 "rlparse.cpp" } break; case 224: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Parser_Lel_inline_item *__ref1 = (Parser_Lel_inline_item*)&rhs[0]->user.inline_item; #line 1351 "rlparse.kl" /* Pass the inline item up. */ (__ref0)->inlineItem = (__ref1)->inlineItem; #line 6453 "rlparse.cpp" } break; case 237: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1381 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::PChar ); #line 6463 "rlparse.cpp" } break; case 238: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1386 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Char ); #line 6473 "rlparse.cpp" } break; case 239: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1391 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Curs ); #line 6483 "rlparse.cpp" } break; case 240: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1396 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, InlineItem::Targs ); #line 6493 "rlparse.cpp" } break; case 241: { Parser_Lel_inline_item *__ref0 = (Parser_Lel_inline_item*)&redLel->user.inline_item; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1401 "rlparse.kl" (__ref0)->inlineItem = new InlineItem( (__ref1)->loc, new NameRef(nameRef), InlineItem::Entry ); #line 6504 "rlparse.cpp" } break; case 243: { #line 1412 "rlparse.kl" nameRef.empty(); #line 6512 "rlparse.cpp" } break; case 245: { #line 1422 "rlparse.kl" /* Insert an initial null pointer val to indicate the existence of the * initial name seperator. */ nameRef.setAs( 0 ); #line 6522 "rlparse.cpp" } break; case 246: { #line 1428 "rlparse.kl" nameRef.empty(); #line 6530 "rlparse.cpp" } break; case 247: { Token *__ref0 = (Token*)&rhs[2]->user.token; #line 1435 "rlparse.kl" nameRef.append( (__ref0)->data ); #line 6539 "rlparse.cpp" } break; case 248: { Token *__ref0 = (Token*)&rhs[0]->user.token; #line 1440 "rlparse.kl" nameRef.append( (__ref0)->data ); #line 6548 "rlparse.cpp" } break; } } if ( lel->child != 0 ) { struct Parser_LangEl *first = lel->child; struct Parser_LangEl *child = lel->child; lel->child = 0; while ( 1 ) { if ( child->type < 226 ) { } else { } numNodes -= 1; if ( child->next == 0 ) break; child = child->next; } child->next = pool; pool = first; } } commit_base: if ( sp > 0 ) { sp -= 1; if ( lel->retry == 0 ) { lel = lel->prev; goto commit_reverse; } else { lel->retry = 0; lel = lel->prev; goto commit_upwards; } } lel->retry = 0; lastFinal = lel; numRetry = 0; } if ( *action & 0x2 ) { int reduction = *action >> 2; struct Parser_LangEl *redLel; if ( input != 0 ) input->causeReduce += 1; if ( pool == 0 ) { if ( freshPos == 8128 ) { struct Parser_Block* newBlock = (struct Parser_Block*) malloc( sizeof(struct Parser_Block) ); newBlock->next = block; block = newBlock; freshEl = newBlock->data; #ifdef KELBT_LOG_ACTIONS cerr << "allocating 8128 LangEls" << endl; #endif freshPos = 0; } redLel = freshEl + freshPos++; } else { redLel = pool; pool = pool->next; } numNodes += 1; redLel->type = Parser_prodLhsIds[reduction]; redLel->reduction = reduction; redLel->child = 0; redLel->next = 0; redLel->retry = (lel->retry << 16); redLel->causeReduce = 0; lel->retry &= 0xffff0000; rhsLen = Parser_prodLengths[reduction]; if ( rhsLen > 0 ) { int r; for ( r = rhsLen-1; r > 0; r-- ) { rhs[r] = stackTop; stackTop = stackTop->next; } rhs[0] = stackTop; stackTop = stackTop->next; rhs[0]->next = 0; } switch ( reduction ) { case 225: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1358 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6643 "rlparse.cpp" } break; case 226: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1359 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6651 "rlparse.cpp" } break; case 227: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1360 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6659 "rlparse.cpp" } break; case 228: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1361 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6667 "rlparse.cpp" } break; case 229: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1362 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6675 "rlparse.cpp" } break; case 230: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1363 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6683 "rlparse.cpp" } break; case 231: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1364 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6691 "rlparse.cpp" } break; case 232: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1371 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6699 "rlparse.cpp" } break; case 233: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1372 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6707 "rlparse.cpp" } break; case 234: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1373 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6715 "rlparse.cpp" } break; case 235: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1374 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6723 "rlparse.cpp" } break; case 236: { Parser_Lel_token_type *__ref0 = (Parser_Lel_token_type*)&redLel->user.token_type; Token *__ref1 = (Token*)&rhs[0]->user.token; #line 1375 "rlparse.kl" (__ref0)->token = *(__ref1); #line 6731 "rlparse.cpp" } break; } #ifdef KELBT_LOG_ACTIONS cerr << "reduced: " << Parser_prodNames[reduction] << " rhsLen: " << rhsLen; #endif if ( action[1] == 0 ) redLel->retry = 0; else { redLel->retry += 0x10000; numRetry += 1; #ifdef KELBT_LOG_ACTIONS cerr << " retry: " << redLel; #endif } #ifdef KELBT_LOG_ACTIONS cerr << endl; #endif if ( rhsLen == 0 ) { redLel->file = lel->file; redLel->line = lel->line; targState = curs; } else { redLel->child = rhs[rhsLen-1]; redLel->file = rhs[0]->file; redLel->line = rhs[0]->line; targState = rhs[0]->state; } if ( induceReject ) { #ifdef KELBT_LOG_ACTIONS cerr << "error induced during reduction of " << Parser_lelNames[redLel->type] << endl; #endif redLel->state = curs; redLel->next = stackTop; stackTop = redLel; curs = targState; goto parseError; } else { redLel->next = input; input = redLel; } } curs = targState; goto again; parseError: #ifdef KELBT_LOG_BACKTRACK cerr << "hit error" << endl; #endif if ( numRetry > 0 ) { struct Parser_LangEl *redLel; if ( input != 0 ) { redLel = input; goto have_undo_element; } while ( 1 ) { redLel = stackTop; if ( stackTop->type < 226 ) { #ifdef KELBT_LOG_BACKTRACK cerr << "backing up over terminal: " << Parser_lelNames[stackTop->type] << endl; #endif stackTop = stackTop->next; redLel->next = input; input = redLel; } else { #ifdef KELBT_LOG_BACKTRACK cerr << "backing up over non-terminal: " << Parser_lelNames[stackTop->type] << endl; #endif stackTop = stackTop->next; struct Parser_LangEl *first = redLel->child; if ( first == 0 ) rhsLen = 0; else { rhsLen = 1; while ( first->next != 0 ) { first = first->next; rhsLen += 1; } first->next = stackTop; stackTop = redLel->child; struct Parser_LangEl *rhsEl = stackTop; int p = rhsLen; while ( p > 0 ) { rhs[--p] = rhsEl; rhsEl = rhsEl->next; } } redLel->next = pool; pool = redLel; numNodes -= 1; if ( input != 0 ) input->causeReduce -= 1; } have_undo_element: if ( redLel->retry == 0 ) { if ( input != 0 && input->causeReduce == 0 ) { #ifdef KELBT_LOG_BACKTRACK cerr << "pushing back: " << Parser_lelNames[input->type] << endl; #endif input->next = queue; queue = input; input = 0; } } else { #ifdef KELBT_LOG_BACKTRACK cerr << "found retry targ: " << redLel << endl; #endif numRetry -= 1; #ifdef KELBT_LOG_BACKTRACK cerr << "found retry: " << redLel << endl; #endif if ( redLel->retry & 0x0000ffff ) curs = input->state; else { input->retry = redLel->retry >> 16; if ( stackTop->state < 0 ) curs = Parser_startState; else { curs = Parser_targs[(int)Parser_indicies[Parser_offsets[stackTop->state] + (stackTop->type - Parser_keys[stackTop->state<<1])]]; } } goto again; } } } curs = -1; errCount += 1; _out: {} #line 1459 "rlparse.kl" return errCount == 0 ? 0 : -1; } void Parser::tryMachineDef( InputLoc &loc, char *name, MachineDef *machineDef, bool isInstance ) { GraphDictEl *newEl = pd->graphDict.insert( name ); if ( newEl != 0 ) { /* New element in the dict, all good. */ newEl->value = new VarDef( name, machineDef ); newEl->isInstance = isInstance; newEl->loc = loc; newEl->value->isExport = exportContext[exportContext.length()-1]; /* It it is an instance, put on the instance list. */ if ( isInstance ) pd->instanceList.append( newEl ); } else { // Recover by ignoring the duplicate. error(loc) << "fsm \"" << name << "\" previously defined" << endl; } } ostream &Parser::parse_error( int tokId, Token &token ) { /* Maintain the error count. */ gblErrorCount += 1; cerr << token.loc << ": "; cerr << "at token "; if ( tokId < 128 ) cerr << "\"" << Parser_lelNames[tokId] << "\""; else cerr << Parser_lelNames[tokId]; if ( token.data != 0 ) cerr << " with data \"" << token.data << "\""; cerr << ": "; return cerr; } int Parser::token( InputLoc &loc, int tokId, char *tokstart, int toklen ) { Token token; token.data = tokstart; token.length = toklen; token.loc = loc; int res = parseLangEl( tokId, &token ); if ( res < 0 ) { parse_error(tokId, token) << "parse error" << endl; exit(1); } return res; } ragel-6.10/ragel/rubycodegen.cpp0000664000175000017500000004375213065111230013564 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "redfsm.h" #include "gendata.h" #include "ragel.h" #include "rubycodegen.h" #include "pcheck.h" #include "vector.h" #include "version.h" #include "common.h" #include "ragel.h" #include "rubytable.h" #include "rubyftable.h" #include "rubyflat.h" #include "rubyfflat.h" #include "rbxgoto.h" using std::ostream; using std::ostringstream; using std::string; using std::cerr; using std::endl; using std::istream; using std::ifstream; using std::ostream; using std::ios; using std::cin; using std::cout; using std::cerr; using std::endl; /* Target ruby impl */ /* Target language and output style. */ extern CodeStyle codeStyle; extern int numSplitPartitions; extern bool noLineDirectives; /* * Callbacks invoked by the XML data parser. */ void rubyLineDirective( ostream &out, const char *fileName, int line ) { if ( noLineDirectives ) return; /* Write a comment containing line info. */ out << "# line " << line << " \""; for ( const char *pc = fileName; *pc != 0; pc++ ) { if ( *pc == '\\' ) out << "\\\\"; else out << *pc; } out << "\"\n"; } void RubyCodeGen::genLineDirective( ostream &out ) { std::streambuf *sbuf = out.rdbuf(); output_filter *filter = static_cast(sbuf); rubyLineDirective( out, filter->fileName, filter->line + 1 ); } string RubyCodeGen::DATA_PREFIX() { if ( !noPrefix ) return FSM_NAME() + "_"; return ""; } std::ostream &RubyCodeGen::STATIC_VAR( string type, string name ) { out << "class << self\n" " attr_accessor :" << name << "\n" "end\n" "self." << name; return out; } std::ostream &RubyCodeGen::OPEN_ARRAY( string type, string name ) { out << "class << self\n" " attr_accessor :" << name << "\n" " private :" << name << ", :" << name << "=\n" "end\n" "self." << name << " = [\n"; return out; } std::ostream &RubyCodeGen::CLOSE_ARRAY() { out << "]\n"; return out; } string RubyCodeGen::ARR_OFF( string ptr, string offset ) { return ptr + "[" + offset + "]"; } string RubyCodeGen::NULL_ITEM() { return "nil"; } string RubyCodeGen::P() { ostringstream ret; if ( pExpr == 0 ) ret << "p"; else { //ret << "("; INLINE_LIST( ret, pExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::PE() { ostringstream ret; if ( peExpr == 0 ) ret << "pe"; else { //ret << "("; INLINE_LIST( ret, peExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::vEOF() { ostringstream ret; if ( eofExpr == 0 ) ret << "eof"; else { //ret << "("; INLINE_LIST( ret, eofExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::vCS() { ostringstream ret; if ( csExpr == 0 ) ret << ACCESS() << "cs"; else { //ret << "("; INLINE_LIST( ret, csExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::TOP() { ostringstream ret; if ( topExpr == 0 ) ret << ACCESS() + "top"; else { //ret << "("; INLINE_LIST( ret, topExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::STACK() { ostringstream ret; if ( stackExpr == 0 ) ret << ACCESS() + "stack"; else { //ret << "("; INLINE_LIST( ret, stackExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::ACT() { ostringstream ret; if ( actExpr == 0 ) ret << ACCESS() + "act"; else { //ret << "("; INLINE_LIST( ret, actExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::TOKSTART() { ostringstream ret; if ( tokstartExpr == 0 ) ret << ACCESS() + "ts"; else { //ret << "("; INLINE_LIST( ret, tokstartExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::TOKEND() { ostringstream ret; if ( tokendExpr == 0 ) ret << ACCESS() + "te"; else { //ret << "("; INLINE_LIST( ret, tokendExpr, 0, false ); //ret << ")"; } return ret.str(); } string RubyCodeGen::DATA() { ostringstream ret; if ( dataExpr == 0 ) ret << ACCESS() + "data"; else { //ret << "("; INLINE_LIST( ret, dataExpr, 0, false ); //ret << ")"; } return ret.str(); } /* Write out the fsm name. */ string RubyCodeGen::FSM_NAME() { return fsmName; } void RubyCodeGen::ACTION( ostream &ret, GenAction *action, int targState, bool inFinish ) { /* Write the preprocessor line info for going into the source file. */ rubyLineDirective( ret, action->loc.fileName, action->loc.line ); /* Write the block and close it off. */ ret << " begin\n"; INLINE_LIST( ret, action->inlineList, targState, inFinish ); ret << " end\n"; } string RubyCodeGen::GET_WIDE_KEY() { if ( redFsm->anyConditions() ) return "_widec"; else return GET_KEY(); } string RubyCodeGen::GET_WIDE_KEY( RedStateAp *state ) { if ( state->stateCondList.length() > 0 ) return "_widec"; else return GET_KEY(); } string RubyCodeGen::GET_KEY() { ostringstream ret; if ( getKeyExpr != 0 ) { /* Emit the user supplied method of retrieving the key. */ ret << "("; INLINE_LIST( ret, getKeyExpr, 0, false ); ret << ")"; } else { /* Expression for retrieving the key, use dereference and read ordinal, * for compatibility with Ruby 1.9. */ ret << DATA() << "[" << P() << "].ord"; } return ret.str(); } string RubyCodeGen::KEY( Key key ) { ostringstream ret; if ( keyOps->isSigned || !hostLang->explicitUnsigned ) ret << key.getVal(); else ret << (unsigned long) key.getVal(); return ret.str(); } /* Write out level number of tabs. Makes the nested binary search nice * looking. */ string RubyCodeGen::TABS( int level ) { string result; while ( level-- > 0 ) result += "\t"; return result; } string RubyCodeGen::INT( int i ) { ostringstream ret; ret << i; return ret.str(); } void RubyCodeGen::CONDITION( ostream &ret, GenAction *condition ) { ret << "\n"; rubyLineDirective( ret, condition->loc.fileName, condition->loc.line ); INLINE_LIST( ret, condition->inlineList, 0, false ); } /* Emit the alphabet data type. */ string RubyCodeGen::ALPH_TYPE() { string ret = keyOps->alphType->data1; if ( keyOps->alphType->data2 != 0 ) { ret += " "; ret += + keyOps->alphType->data2; } return ret; } /* Emit the alphabet data type. */ string RubyCodeGen::WIDE_ALPH_TYPE() { string ret; if ( redFsm->maxKey <= keyOps->maxKey ) ret = ALPH_TYPE(); else { long long maxKeyVal = redFsm->maxKey.getLongLong(); HostType *wideType = keyOps->typeSubsumes( keyOps->isSigned, maxKeyVal ); assert( wideType != 0 ); ret = wideType->data1; if ( wideType->data2 != 0 ) { ret += " "; ret += wideType->data2; } } return ret; } string RubyCodeGen::ARRAY_TYPE( unsigned long maxVal ) { long long maxValLL = (long long) maxVal; HostType *arrayType = keyOps->typeSubsumes( maxValLL ); assert( arrayType != 0 ); string ret = arrayType->data1; if ( arrayType->data2 != 0 ) { ret += " "; ret += arrayType->data2; } return ret; } /* Write out the array of actions. */ std::ostream &RubyCodeGen::ACTIONS_ARRAY() { START_ARRAY_LINE(); int totalActions = 0; ARRAY_ITEM( INT(0), ++totalActions, false ); for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ ARRAY_ITEM( INT(act->key.length()), ++totalActions, false ); for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) { ARRAY_ITEM( INT(item->value->actionId), ++totalActions, (act.last() && item.last()) ); } } END_ARRAY_LINE(); return out; } void RubyCodeGen::STATE_IDS() { if ( redFsm->startState != 0 ) STATIC_VAR( "int", START() ) << " = " << START_STATE_ID() << ";\n"; if ( !noFinal ) STATIC_VAR( "int" , FIRST_FINAL() ) << " = " << FIRST_FINAL_STATE() << ";\n"; if ( !noError ) STATIC_VAR( "int", ERROR() ) << " = " << ERROR_STATE() << ";\n"; out << "\n"; if ( !noEntry && entryPointNames.length() > 0 ) { for ( EntryNameVect::Iter en = entryPointNames; en.lte(); en++ ) { STATIC_VAR( "int", DATA_PREFIX() + "en_" + *en ) << " = " << entryPointIds[en.pos()] << ";\n"; } out << "\n"; } } std::ostream &RubyCodeGen::START_ARRAY_LINE() { out << "\t"; return out; } std::ostream &RubyCodeGen::ARRAY_ITEM( string item, int count, bool last ) { out << item; if ( !last ) { out << ", "; if ( count % IALL == 0 ) { END_ARRAY_LINE(); START_ARRAY_LINE(); } } return out; } std::ostream &RubyCodeGen::END_ARRAY_LINE() { out << "\n"; return out; } /* Emit the offset of the start state as a decimal integer. */ string RubyCodeGen::START_STATE_ID() { ostringstream ret; ret << redFsm->startState->id; return ret.str(); }; string RubyCodeGen::ERROR_STATE() { ostringstream ret; if ( redFsm->errState != 0 ) ret << redFsm->errState->id; else ret << "-1"; return ret.str(); } string RubyCodeGen::FIRST_FINAL_STATE() { ostringstream ret; if ( redFsm->firstFinState != 0 ) ret << redFsm->firstFinState->id; else ret << redFsm->nextStateId; return ret.str(); } string RubyCodeGen::ACCESS() { ostringstream ret; if ( accessExpr != 0 ) INLINE_LIST( ret, accessExpr, 0, false ); return ret.str(); } /* Write out an inline tree structure. Walks the list and possibly calls out * to virtual functions than handle language specific items in the tree. */ void RubyCodeGen::INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Text: ret << item->data; break; case GenInlineItem::Goto: GOTO( ret, item->targState->id, inFinish ); break; case GenInlineItem::Call: CALL( ret, item->targState->id, targState, inFinish ); break; case GenInlineItem::Next: NEXT( ret, item->targState->id, inFinish ); break; case GenInlineItem::Ret: RET( ret, inFinish ); break; case GenInlineItem::PChar: ret << P(); break; case GenInlineItem::Char: ret << GET_KEY(); break; case GenInlineItem::Hold: ret << P() << " = " << P() << " - 1;"; break; case GenInlineItem::Exec: EXEC( ret, item, targState, inFinish ); break; case GenInlineItem::Curs: ret << "(_ps)"; break; case GenInlineItem::Targs: ret << "(" << vCS() << ")"; break; case GenInlineItem::Entry: ret << item->targState->id; break; case GenInlineItem::GotoExpr: GOTO_EXPR( ret, item, inFinish ); break; case GenInlineItem::CallExpr: CALL_EXPR( ret, item, targState, inFinish ); break; case GenInlineItem::NextExpr: NEXT_EXPR( ret, item, inFinish ); break; case GenInlineItem::LmSwitch: LM_SWITCH( ret, item, targState, inFinish ); break; case GenInlineItem::LmSetActId: SET_ACT( ret, item ); break; case GenInlineItem::LmSetTokEnd: SET_TOKEND( ret, item ); break; case GenInlineItem::LmGetTokEnd: GET_TOKEND( ret, item ); break; case GenInlineItem::LmInitTokStart: INIT_TOKSTART( ret, item ); break; case GenInlineItem::LmInitAct: INIT_ACT( ret, item ); break; case GenInlineItem::LmSetTokStart: SET_TOKSTART( ret, item ); break; case GenInlineItem::SubAction: SUB_ACTION( ret, item, targState, inFinish ); break; case GenInlineItem::Break: BREAK( ret, targState ); break; } } } void RubyCodeGen::EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { /* The parser gives fexec two children. The double brackets are for D * code. If the inline list is a single word it will get interpreted as a * C-style cast by the D compiler. */ ret << " begin " << P() << " = (("; INLINE_LIST( ret, item->children, targState, inFinish ); ret << "))-1; end\n"; } void RubyCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { ret << " case " << ACT() << "\n"; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) ret << " else\n"; else ret << " when " << lma->lmId << " then\n"; /* Write the block and close it off. */ ret << " begin"; INLINE_LIST( ret, lma->children, targState, inFinish ); ret << "end\n"; } ret << "end \n\t"; } void RubyCodeGen::SET_ACT( ostream &ret, GenInlineItem *item ) { ret << ACT() << " = " << item->lmId << ";"; } void RubyCodeGen::INIT_TOKSTART( ostream &ret, GenInlineItem *item ) { ret << TOKSTART() << " = " << NULL_ITEM() << ";"; } void RubyCodeGen::INIT_ACT( ostream &ret, GenInlineItem *item ) { ret << ACT() << " = 0\n"; } void RubyCodeGen::SET_TOKSTART( ostream &ret, GenInlineItem *item ) { ret << TOKSTART() << " = " << P() << "\n"; } void RubyCodeGen::SET_TOKEND( ostream &ret, GenInlineItem *item ) { /* The tokend action sets tokend. */ ret << TOKEND() << " = " << P(); if ( item->offset != 0 ) out << "+" << item->offset; out << "\n"; } void RubyCodeGen::GET_TOKEND( ostream &ret, GenInlineItem *item ) { ret << TOKEND(); } void RubyCodeGen::SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish ) { if ( item->children->length() > 0 ) { /* Write the block and close it off. */ ret << " begin "; INLINE_LIST( ret, item->children, targState, inFinish ); ret << " end\n"; } } int RubyCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; return act; } ostream &RubyCodeGen::source_warning( const InputLoc &loc ) { cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: "; return cerr; } ostream &RubyCodeGen::source_error( const InputLoc &loc ) { gblErrorCount += 1; assert( sourceFileName != 0 ); cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": "; return cerr; } void RubyCodeGen::finishRagelDef() { if ( codeStyle == GenGoto || codeStyle == GenFGoto || codeStyle == GenIpGoto || codeStyle == GenSplit ) { /* For directly executable machines there is no required state * ordering. Choose a depth-first ordering to increase the * potential for fall-throughs. */ redFsm->depthFirstOrdering(); } else { /* The frontend will do this for us, but it may be a good idea to * force it if the intermediate file is edited. */ redFsm->sortByStateId(); } /* Choose default transitions and the single transition. */ redFsm->chooseDefaultSpan(); /* Maybe do flat expand, otherwise choose single. */ if ( codeStyle == GenFlat || codeStyle == GenFFlat ) redFsm->makeFlat(); else redFsm->chooseSingle(); /* If any errors have occured in the input file then don't write anything. */ if ( gblErrorCount > 0 ) return; if ( codeStyle == GenSplit ) redFsm->partitionFsm( numSplitPartitions ); if ( codeStyle == GenIpGoto || codeStyle == GenSplit ) redFsm->setInTrans(); /* Anlayze Machine will find the final action reference counts, among * other things. We will use these in reporting the usage * of fsm directives in action code. */ analyzeMachine(); /* Determine if we should use indicies. */ calcIndexSize(); } /* Determine if we should use indicies or not. */ void RubyCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } unsigned int RubyCodeGen::arrayTypeSize( unsigned long maxVal ) { long long maxValLL = (long long) maxVal; HostType *arrayType = keyOps->typeSubsumes( maxValLL ); assert( arrayType != 0 ); return arrayType->size; } void RubyCodeGen::writeInit() { out << "begin\n"; out << " " << P() << " ||= 0\n"; if ( !noEnd ) out << " " << PE() << " ||= " << DATA() << ".length\n"; if ( !noCS ) out << " " << vCS() << " = " << START() << "\n"; /* If there are any calls, then the stack top needs initialization. */ if ( redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << " " << TOP() << " = 0\n"; if ( hasLongestMatch ) { out << " " << TOKSTART() << " = " << NULL_ITEM() << "\n" " " << TOKEND() << " = " << NULL_ITEM() << "\n" " " << ACT() << " = 0\n"; } out << "end\n"; } void RubyCodeGen::writeExports() { if ( exportList.length() > 0 ) { for ( ExportList::Iter ex = exportList; ex.lte(); ex++ ) { STATIC_VAR( ALPH_TYPE(), DATA_PREFIX() + "ex_" + ex->name ) << " = " << KEY(ex->key) << "\n"; } out << "\n"; } } void RubyCodeGen::writeStart() { out << START_STATE_ID(); } void RubyCodeGen::writeFirstFinal() { out << FIRST_FINAL_STATE(); } void RubyCodeGen::writeError() { out << ERROR_STATE(); } /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/goftable.cpp0000664000175000017500000002455513065111230013041 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "goftable.h" #include "redfsm.h" #include "gendata.h" using std::endl; /* Determine if we should use indicies or not. */ void GoFTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActListId) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActListId) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &GoFTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &GoFTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &GoFTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &GoFTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFTabCodeGen::TO_STATE_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << endl; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFTabCodeGen::FROM_STATE_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << endl; } } genLineDirective( out ); return out; } std::ostream &GoFTabCodeGen::EOF_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); out << endl; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFTabCodeGen::ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << endl; } } genLineDirective( out ); return out; } void GoFTabCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << endl; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << endl; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << endl; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << endl; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << endl; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << endl; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << endl; } STATE_IDS(); } void GoFTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {" << endl << " var _klen " << INT() << endl; if ( redFsm->anyRegCurStateRef() ) out << " var _ps " << INT() << endl; out << " var _keys " << INT() << endl << " var _trans " << INT() << endl; if ( redFsm->anyConditions() ) out << " var _widec " << WIDE_ALPH_TYPE() << endl; out << endl; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " == " << PE() << " {" << endl << " goto _test_eof" << endl << " }" << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } out << "_resume:" << endl; if ( redFsm->anyFromStateActions() ) { out << " switch " << FSA() << "[" << vCS() << "] {" << endl; FROM_STATE_ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); out << "_match:" << endl; if ( useIndicies ) out << " _trans = " << CAST(INT(), I() + "[_trans]") << endl; if ( redFsm->anyEofTrans() ) out << "_eof_trans:" << endl; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << endl; out << " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl << endl; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] == 0 {" << endl << " goto _again" << endl << " }" << endl << endl << " switch " << TA() << "[_trans] {" << endl; ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:" << endl; if ( redFsm->anyToStateActions() ) { out << " switch " << TSA() << "[" << vCS() << "] {" << endl; TO_STATE_ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } if ( !noEnd ) { out << " if " << P() << "++; " << P() << " != " << PE() << " {" << endl << " goto _resume" << endl << " }" << endl; } else { out << " " << P() << "++" << endl << " goto _resume" << endl; } if ( testEofUsed ) out << " _test_eof: {}" << endl; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << " {" << endl; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0 {" << endl << " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl << " goto _eof_trans" << endl << " }" << endl; } if ( redFsm->anyEofActions() ) { out << " switch " << EA() << "[" << vCS() << "] {" << endl; EOF_ACTION_SWITCH(2); out << " }" << endl; } out << " }" << endl << endl; } if ( outLabelUsed ) out << " _out: {}" << endl; out << " }" << endl; } ragel-6.10/ragel/cdtable.h0000664000175000017500000000662313065111230012315 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDTABLE_H #define _CDTABLE_H #include #include "cdcodegen.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; /* * TabCodeGen */ class TabCodeGen : virtual public FsmCodeGen { public: TabCodeGen( ostream &out ) : FsmCodeGen(out) {} virtual ~TabCodeGen() { } virtual void writeData(); virtual void writeExec(); protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &COND_KEYS(); std::ostream &COND_SPACES(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &COND_OFFSETS(); std::ostream &KEY_OFFSETS(); std::ostream &INDEX_OFFSETS(); std::ostream &COND_LENS(); std::ostream &SINGLE_LENS(); std::ostream &RANGE_LENS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); std::ostream &TRANS_TARGS_WI(); std::ostream &TRANS_ACTIONS_WI(); void LOCATE_TRANS(); void COND_TRANSLATE(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState, bool csForced ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void calcIndexSize(); }; /* * CTabCodeGen */ struct CTabCodeGen : public TabCodeGen, public CCodeGen { CTabCodeGen( ostream &out ) : FsmCodeGen(out), TabCodeGen(out), CCodeGen(out) {} }; /* * DTabCodeGen */ struct DTabCodeGen : public TabCodeGen, public DCodeGen { DTabCodeGen( ostream &out ) : FsmCodeGen(out), TabCodeGen(out), DCodeGen(out) {} }; /* * D2TabCodeGen */ struct D2TabCodeGen : public TabCodeGen, public D2CodeGen { D2TabCodeGen( ostream &out ) : FsmCodeGen(out), TabCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/cdgoto.cpp0000664000175000017500000005364413065111230012536 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdgoto.h" #include "redfsm.h" #include "bstmap.h" #include "gendata.h" /* Emit the goto to take for a given transition. */ std::ostream &GotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { out << TABS(level) << "goto tr" << trans->id << ";"; return out; } std::ostream &GotoCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &GotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &GotoCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, true, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &GotoCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } void GotoCodeGen::GOTO_HEADER( RedStateAp *state ) { /* Label the state. */ out << "case " << state->id << ":\n"; } void GotoCodeGen::emitSingleSwitch( RedStateAp *state ) { /* Load up the singles. */ int numSingles = state->outSingle.length(); RedTransEl *data = state->outSingle.data; if ( numSingles == 1 ) { /* If there is a single single key then write it out as an if. */ out << "\tif ( " << GET_WIDE_KEY(state) << " == " << WIDE_KEY(state, data[0].lowKey) << " )\n\t\t"; /* Virtual function for writing the target of the transition. */ TRANS_GOTO(data[0].value, 0) << "\n"; } else if ( numSingles > 1 ) { /* Write out single keys in a switch if there is more than one. */ out << "\tswitch( " << GET_WIDE_KEY(state) << " ) {\n"; /* Write out the single indicies. */ for ( int j = 0; j < numSingles; j++ ) { out << "\t\tcase " << WIDE_KEY(state, data[j].lowKey) << ": "; TRANS_GOTO(data[j].value, 0) << "\n"; } /* Emits a default case for D code. */ SWITCH_DEFAULT(); /* Close off the transition switch. */ out << "\t}\n"; } } void GotoCodeGen::emitRangeBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; RedTransEl *data = state->outRange.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid].lowKey == keyOps->minKey; bool limitHigh = data[mid].highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " < " << WIDE_KEY(state, data[mid].lowKey) << " ) {\n"; emitRangeBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "} else if ( " << GET_WIDE_KEY(state) << " > " << WIDE_KEY(state, data[mid].highKey) << " ) {\n"; emitRangeBSearch( state, level+1, mid+1, high ); out << TABS(level) << "} else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " < " << WIDE_KEY(state, data[mid].lowKey) << " ) {\n"; emitRangeBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "} else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << "} else if ( " << GET_WIDE_KEY(state) << " <= " << WIDE_KEY(state, data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " > " << WIDE_KEY(state, data[mid].highKey) << " ) {\n"; emitRangeBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "} else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << "} else if ( " << GET_WIDE_KEY(state) << " >= " << WIDE_KEY(state, data[mid].lowKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if ( " << WIDE_KEY(state, data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " && " << GET_WIDE_KEY(state) << " <= " << WIDE_KEY(state, data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " <= " << WIDE_KEY(state, data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if ( " << WIDE_KEY(state, data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { /* Both high and low are at the limit. No tests to do. */ TRANS_GOTO(data[mid].value, level+1) << "\n"; } } } void GotoCodeGen::STATE_GOTO_ERROR() { /* Label the state and bail immediately. */ outLabelUsed = true; RedStateAp *state = redFsm->errState; out << "case " << state->id << ":\n"; out << " goto _out;\n"; } void GotoCodeGen::COND_TRANSLATE( GenStateCond *stateCond, int level ) { GenCondSpace *condSpace = stateCond->condSpace; out << TABS(level) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(level) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } } void GotoCodeGen::emitCondBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; GenStateCond **data = state->stateCondVect.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid]->lowKey == keyOps->minKey; bool limitHigh = data[mid]->highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if ( " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " ) {\n"; emitCondBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "} else if ( " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " ) {\n"; emitCondBSearch( state, level+1, mid+1, high ); out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if ( " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " ) {\n"; emitCondBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { out << TABS(level) << "} else if ( " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if ( " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " ) {\n"; emitCondBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { out << TABS(level) << "} else if ( " << GET_KEY() << " >= " << KEY(data[mid]->lowKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " && " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if ( " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " )\n {"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { /* Both high and low are at the limit. No tests to do. */ COND_TRANSLATE(data[mid], level); } } } std::ostream &GotoCodeGen::STATE_GOTOS() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st == redFsm->errState ) STATE_GOTO_ERROR(); else { /* Writing code above state gotos. */ GOTO_HEADER( st ); if ( st->stateCondVect.length() > 0 ) { out << " _widec = " << GET_KEY() << ";\n"; emitCondBSearch( st, 1, 0, st->stateCondVect.length() - 1 ); } /* Try singles. */ if ( st->outSingle.length() > 0 ) emitSingleSwitch( st ); /* Default case is to binary search for the ranges, if that fails then */ if ( st->outRange.length() > 0 ) emitRangeBSearch( st, 1, 0, st->outRange.length() - 1 ); /* Write the default transition. */ TRANS_GOTO( st->defTrans, 1 ) << "\n"; } } return out; } std::ostream &GotoCodeGen::TRANSITIONS() { /* Emit any transitions that have functions and that go to * this state. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Write the label for the transition so it can be jumped to. */ out << " tr" << trans->id << ": "; /* Destination state. */ if ( trans->action != 0 && trans->action->anyCurStateRef() ) out << "_ps = " << vCS() << ";"; out << vCS() << " = " << trans->targ->id << "; "; if ( trans->action != 0 ) { /* Write out the transition func. */ out << "goto f" << trans->action->actListId << ";\n"; } else { /* No code to execute, just loop around. */ out << "goto _again;\n"; } } return out; } std::ostream &GotoCodeGen::EXEC_FUNCS() { /* Make labels that set acts and jump to execFuncs. Loop func indicies. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { out << " f" << redAct->actListId << ": " << "_acts = " << ARR_OFF(A(), itoa( redAct->location+1 ) ) << ";" " goto execFuncs;\n"; } } out << "\n" "execFuncs:\n" " _nacts = *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" " goto _again;\n"; return out; } unsigned int GotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; return act; } unsigned int GotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; return act; } unsigned int GotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; return act; } std::ostream &GotoCodeGen::TO_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = TO_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &GotoCodeGen::FROM_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = FROM_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &GotoCodeGen::EOF_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = EOF_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &GotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << "\t\tcase " << st->id << ": "; /* Write the goto func. */ out << "goto f" << st->eofAction->actListId << ";\n"; } } return out; } void GotoCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{"; ret << vCS() << " = " << gotoDest << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void GotoCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{"; ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void GotoCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void GotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void GotoCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void GotoCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; } void GotoCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void GotoCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish, false ); ret << ");"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void GotoCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];"; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false, false ); ret << "}"; } if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void GotoCodeGen::BREAK( ostream &ret, int targState, bool csForced ) { outLabelUsed = true; ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }"; } void GotoCodeGen::writeData() { if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void GotoCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "_acts;\n" " " << UINT() << " _nacts;\n"; } if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; out << "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << ARR_OFF( A(), FSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } out << " switch ( " << vCS() << " ) {\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " }\n" "\n"; TRANSITIONS() << "\n"; if ( redFsm->anyRegActions() ) EXEC_FUNCS() << "\n"; out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << ARR_OFF( A(), TSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " switch ( " << vCS() << " ) {\n"; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " case " << st->id << ": goto tr" << st->eofTrans->id << ";\n"; } SWITCH_DEFAULT() << " }\n"; } if ( redFsm->anyEofActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "__acts = " << ARR_OFF( A(), EA() + "[" + vCS() + "]" ) << ";\n" " " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n" " while ( __nacts-- > 0 ) {\n" " switch ( *__acts++ ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/mltable.cpp0000664000175000017500000007144613065111230012677 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "mltable.h" #include "redfsm.h" #include "gendata.h" /* Determine if we should use indicies or not. */ void OCamlTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &OCamlTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &OCamlTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &OCamlTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &OCamlTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &OCamlTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &OCamlTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &OCamlTabCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, true ); } } genLineDirective( out ); return out; } std::ostream &OCamlTabCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\t| " << act->actionId << " -> \n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &OCamlTabCodeGen::COND_OFFSETS() { out << "\t"; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the key offset ahead. */ curKeyOffset += st->stateCondList.length(); } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::KEY_OFFSETS() { out << "\t"; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the key offset ahead. */ curKeyOffset += st->outSingle.length() + st->outRange.length()*2; } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::INDEX_OFFSETS() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ curIndOffset += st->outSingle.length() + st->outRange.length(); if ( st->defTrans != 0 ) curIndOffset += 1; } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::COND_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->stateCondList.length(); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::SINGLE_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->outSingle.length(); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::RANGE_LENS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit length of range index. */ out << st->outRange.length(); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::TO_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::FROM_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::EOF_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::EOF_TRANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlTabCodeGen::COND_KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Lower key. */ out << ALPHA_KEY( sc->lowKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << ALPHA_KEY( sc->highKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlTabCodeGen::COND_SPACES() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Cond Space id. */ out << sc->condSpace->condSpaceId << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlTabCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << ALPHA_KEY( stel->lowKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ out << ALPHA_KEY( rtel->lowKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; /* Upper key. */ out << ALPHA_KEY( rtel->highKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlTabCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << stel->value->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { out << rtel->value->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { out << st->defTrans->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlTabCodeGen::TRANS_TARGS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; out << trans->targ->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; out << trans->targ->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; out << trans->targ->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; out << trans->targ->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlTabCodeGen::TRANS_ACTIONS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; TRANS_ACTION( trans ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; TRANS_ACTION( trans ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; TRANS_ACTION( trans ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; TRANS_ACTION( trans ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlTabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ARR_SEP(); if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } std::ostream &OCamlTabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ARR_SEP(); if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } void OCamlTabCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "begin " << vCS() << " <- " << gotoDest << "; " << CTRL_FLOW() << "raise Goto_again end"; } void OCamlTabCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "begin " << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << "raise Goto_again end"; } void OCamlTabCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void OCamlTabCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void OCamlTabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " <- " << nextDest << ";"; } void OCamlTabCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void OCamlTabCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin " << AT( STACK(), POST_INCR(TOP()) ) << " <- " << vCS() << "; "; ret << vCS() << " <- " << callDest << "; " << CTRL_FLOW() << "raise Goto_again end "; if ( prePushExpr != 0 ) ret << "end"; } void OCamlTabCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin " << AT(STACK(), POST_INCR(TOP()) ) << " <- " << vCS() << "; " << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << "); " << CTRL_FLOW() << "raise Goto_again end "; if ( prePushExpr != 0 ) ret << "end"; } void OCamlTabCodeGen::RET( ostream &ret, bool inFinish ) { ret << "begin " << vCS() << " <- " << AT(STACK(), PRE_DECR(TOP()) ) << "; "; if ( postPopExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "end "; } ret << CTRL_FLOW() << "raise Goto_again end"; } void OCamlTabCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; ret << "begin " << P() << " <- " << P() << " + 1; " << CTRL_FLOW() << "raise Goto_out end"; } void OCamlTabCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); out << "type " << TYPE_STATE() << " = { mutable keys : int; mutable trans : int; mutable acts : int; mutable nacts : int; }" << TOP_SEP(); out << "exception Goto_match" << TOP_SEP(); out << "exception Goto_again" << TOP_SEP(); out << "exception Goto_eof_trans" << TOP_SEP(); } void OCamlTabCodeGen::LOCATE_TRANS() { out << " state.keys <- " << AT( KO(), vCS() ) << ";\n" " state.trans <- " << CAST(transType) << AT( IO(), vCS() ) << ";\n" "\n" " let klen = " << AT( SL(), vCS() ) << " in\n" " if klen > 0 then begin\n" " let lower : " << signedKeysType << " ref = ref state.keys in\n" " let upper : " << signedKeysType << " ref = ref " << CAST(signedKeysType) << "(state.keys + klen - 1) in\n" " while !upper >= !lower do\n" " let mid = " << CAST(signedKeysType) << " (!lower + ((!upper - !lower) / 2)) in\n" " if " << GET_WIDE_KEY() << " < " << AT( K(), "mid" ) << " then\n" " upper := " << CAST(signedKeysType) << " (mid - 1)\n" " else if " << GET_WIDE_KEY() << " > " << AT( K(), "mid" ) << " then\n" " lower := " << CAST(signedKeysType) << " (mid + 1)\n" " else begin\n" " state.trans <- state.trans + " << CAST(transType) << " (mid - state.keys);\n" " raise Goto_match;\n" " end\n" " done;\n" " state.keys <- state.keys + " << CAST(keysType) << " klen;\n" " state.trans <- state.trans + " << CAST(transType) << " klen;\n" " end;\n" "\n" " let klen = " << AT( RL(), vCS() ) << " in\n" " if klen > 0 then begin\n" " let lower : " << signedKeysType << " ref = ref state.keys in\n" " let upper : " << signedKeysType << " ref = ref " << CAST(signedKeysType) << "(state.keys + (klen * 2) - 2) in\n" " while !upper >= !lower do\n" " let mid = " << CAST(signedKeysType) << " (!lower + (((!upper - !lower) / 2) land (lnot 1))) in\n" " if " << GET_WIDE_KEY() << " < " << AT( K() , "mid" ) << " then\n" " upper := " << CAST(signedKeysType) << " (mid - 2)\n" " else if " << GET_WIDE_KEY() << " > " << AT( K(), "mid+1" ) << " then\n" " lower := " << CAST(signedKeysType) << " (mid + 2)\n" " else begin\n" " state.trans <- state.trans + " << CAST(transType) << "((mid - state.keys) / 2);\n" " raise Goto_match;\n" " end\n" " done;\n" " state.trans <- state.trans + " << CAST(transType) << " klen;\n" " end;\n" "\n"; } void OCamlTabCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << ";\n" " _klen = " << CL() << "[" << vCS() << "];\n" " _keys = " << CAST(keysType) << " ("<< CO() << "[" << vCS() << "]*2);\n" " if ( _klen > 0 ) {\n" " " << signedKeysType << " _lower = _keys;\n" " " << signedKeysType << " _mid;\n" " " << signedKeysType << " _upper = " << CAST(signedKeysType) << " (_keys + (_klen<<1) - 2);\n" " while (true) {\n" " if ( _upper < _lower )\n" " break;\n" "\n" " _mid = " << CAST(signedKeysType) << " (_lower + (((_upper-_lower) >> 1) & ~1));\n" " if ( " << GET_WIDE_KEY() << " < " << CK() << "[_mid] )\n" " _upper = " << CAST(signedKeysType) << " (_mid - 2);\n" " else if ( " << GET_WIDE_KEY() << " > " << CK() << "[_mid+1] )\n" " _lower = " << CAST(signedKeysType) << " (_mid + 2);\n" " else {\n" " switch ( " << C() << "[" << CO() << "[" << vCS() << "]" " + ((_mid - _keys)>>1)] ) {\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId << ": {\n"; out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } out << " break;\n" " }\n"; } SWITCH_DEFAULT(); out << " }\n" " break;\n" " }\n" " }\n" " }\n" "\n"; } void OCamlTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " begin\n"; // " " << klenType << " _klen"; // if ( redFsm->anyRegCurStateRef() ) // out << ", _ps"; /* out << " " << transType << " _trans;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " int _acts;\n" " int _nacts;\n"; } out << " " << keysType << " _keys;\n" "\n"; // " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n" */ out << " let state = { keys = 0; trans = 0; acts = 0; nacts = 0; } in\n" " let rec do_start () =\n"; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " = " << PE() << " then\n" " do_test_eof ()\n" "\telse\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " = " << redFsm->errState->id << " then\n" " do_out ()\n" "\telse\n"; } out << "\tdo_resume ()\n"; out << "and do_resume () =\n"; if ( redFsm->anyFromStateActions() ) { out << " state.acts <- " << AT( FSA(), vCS() ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n" " done;\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); out << "\tbegin try\n"; LOCATE_TRANS(); out << "\twith Goto_match -> () end;\n"; out << "\tdo_match ()\n"; out << "and do_match () =\n"; if ( useIndicies ) out << " state.trans <- " << CAST(transType) << AT( I(), "state.trans" ) << ";\n"; out << "\tdo_eof_trans ()\n"; // if ( redFsm->anyEofTrans() ) out << "and do_eof_trans () =\n"; if ( redFsm->anyRegCurStateRef() ) out << " let ps = " << vCS() << " in\n"; out << " " << vCS() << " <- " << AT( TT() ,"state.trans" ) << ";\n" "\n"; if ( redFsm->anyRegActions() ) { out << "\tbegin try\n" " match " << AT( TA(), "state.trans" ) << " with\n" "\t| 0 -> raise Goto_again\n" "\t| _ ->\n" " state.acts <- " << AT( TA(), "state.trans" ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" " done\n" "\twith Goto_again -> () end;\n"; } out << "\tdo_again ()\n"; // if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || // redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "\tand do_again () =\n"; if ( redFsm->anyToStateActions() ) { out << " state.acts <- " << AT( TSA(), vCS() ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n" " done;\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " match " << vCS() << " with\n" "\t| " << redFsm->errState->id << " -> do_out ()\n" "\t| _ ->\n"; } out << "\t" << P() << " <- " << P() << " + 1;\n"; if ( !noEnd ) { out << " if " << P() << " <> " << PE() << " then\n" " do_resume ()\n" "\telse do_test_eof ()\n"; } else { out << " do_resume ()\n"; } // if ( testEofUsed ) out << "and do_test_eof () =\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " = " << vEOF() << " then\n" " begin try\n"; if ( redFsm->anyEofTrans() ) { out << " if " << AT( ET(), vCS() ) << " > 0 then\n" " begin\n" " state.trans <- " << CAST(transType) << "(" << AT( ET(), vCS() ) << " - 1);\n" " raise Goto_eof_trans;\n" " end;\n"; } if ( redFsm->anyEofActions() ) { out << " let __acts = ref " << AT( EA(), vCS() ) << " in\n" " let __nacts = ref " << AT( A(), "!__acts" ) << " in\n" " incr __acts;\n" " while !__nacts > 0 do\n" " decr __nacts;\n" " begin match " << AT( A(), POST_INCR("__acts.contents") ) << " with\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" " done\n"; } out << " with Goto_again -> do_again ()\n" " | Goto_eof_trans -> do_eof_trans () end\n" "\n"; } else { out << "\t()\n"; } if ( outLabelUsed ) out << " and do_out () = ()\n"; out << "\tin do_start ()\n"; out << " end;\n"; } void OCamlTabCodeGen::initVarTypes() { int klenMax = MAX(MAX(redFsm->maxCondLen, redFsm->maxRangeLen), redFsm->maxSingleLen); int keysMax = MAX(MAX(redFsm->maxKeyOffset, klenMax), redFsm->maxCondOffset); int transMax = MAX(MAX(redFsm->maxIndex+1, redFsm->maxIndexOffset), keysMax); transMax = MAX(transMax, klenMax); transType = ARRAY_TYPE(transMax); klenType = ARRAY_TYPE(klenMax); keysType = ARRAY_TYPE(keysMax); signedKeysType = ARRAY_TYPE(keysMax, true); } ragel-6.10/ragel/inputdata.cpp0000664000175000017500000001766313065111230013251 00000000000000/* * Copyright 2008 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "common.h" #include "inputdata.h" #include "parsedata.h" #include "rlparse.h" #include #include "dotcodegen.h" using std::cout; using std::cerr; using std::endl; using std::ios; /* Invoked by the parser when the root element is opened. */ void InputData::cdDefaultFileName( const char *inputFile ) { /* If the output format is code and no output file name is given, then * make a default. */ if ( outputFileName == 0 ) { const char *ext = findFileExtension( inputFile ); if ( ext != 0 && strcmp( ext, ".rh" ) == 0 ) outputFileName = fileNameFromStem( inputFile, ".h" ); else { const char *defExtension = 0; switch ( hostLang->lang ) { case HostLang::C: defExtension = ".c"; break; case HostLang::D: defExtension = ".d"; break; case HostLang::D2: defExtension = ".d"; break; default: break; } outputFileName = fileNameFromStem( inputFile, defExtension ); } } } /* Invoked by the parser when the root element is opened. */ void InputData::goDefaultFileName( const char *inputFile ) { /* If the output format is code and no output file name is given, then * make a default. */ if ( outputFileName == 0 ) outputFileName = fileNameFromStem( inputFile, ".go" ); } /* Invoked by the parser when the root element is opened. */ void InputData::javaDefaultFileName( const char *inputFile ) { /* If the output format is code and no output file name is given, then * make a default. */ if ( outputFileName == 0 ) outputFileName = fileNameFromStem( inputFile, ".java" ); } /* Invoked by the parser when the root element is opened. */ void InputData::rubyDefaultFileName( const char *inputFile ) { /* If the output format is code and no output file name is given, then * make a default. */ if ( outputFileName == 0 ) outputFileName = fileNameFromStem( inputFile, ".rb" ); } /* Invoked by the parser when the root element is opened. */ void InputData::csharpDefaultFileName( const char *inputFile ) { /* If the output format is code and no output file name is given, then * make a default. */ if ( outputFileName == 0 ) { const char *ext = findFileExtension( inputFile ); if ( ext != 0 && strcmp( ext, ".rh" ) == 0 ) outputFileName = fileNameFromStem( inputFile, ".h" ); else outputFileName = fileNameFromStem( inputFile, ".cs" ); } } /* Invoked by the parser when the root element is opened. */ void InputData::ocamlDefaultFileName( const char *inputFile ) { /* If the output format is code and no output file name is given, then * make a default. */ if ( outputFileName == 0 ) outputFileName = fileNameFromStem( inputFile, ".ml" ); } void InputData::makeOutputStream() { if ( ! generateDot && ! generateXML ) { switch ( hostLang->lang ) { case HostLang::C: case HostLang::D: case HostLang::D2: cdDefaultFileName( inputFileName ); break; case HostLang::Java: javaDefaultFileName( inputFileName ); break; case HostLang::Go: goDefaultFileName( inputFileName ); break; case HostLang::Ruby: rubyDefaultFileName( inputFileName ); break; case HostLang::CSharp: csharpDefaultFileName( inputFileName ); break; case HostLang::OCaml: ocamlDefaultFileName( inputFileName ); break; } } /* Make sure we are not writing to the same file as the input file. */ if ( outputFileName != 0 ) { if ( strcmp( inputFileName, outputFileName ) == 0 ) { error() << "output file \"" << outputFileName << "\" is the same as the input file" << endl; } /* Create the filter on the output and open it. */ outFilter = new output_filter( outputFileName ); /* Open the output stream, attaching it to the filter. */ outStream = new ostream( outFilter ); } else { /* Writing out ot std out. */ outStream = &cout; } } void InputData::openOutput() { if ( outFilter != 0 ) { outFilter->open( outputFileName, ios::out|ios::trunc ); if ( !outFilter->is_open() ) { error() << "error opening " << outputFileName << " for writing" << endl; exit(1); } } } void InputData::prepareMachineGen() { if ( generateDot ) { /* Locate a machine spec to generate dot output for. We can only emit. * Dot takes one graph at a time. */ if ( machineSpec != 0 ) { /* Machine specified. */ ParserDictEl *pdEl = parserDict.find( machineSpec ); if ( pdEl == 0 ) error() << "could not locate machine specified with -S and/or -M" << endp; dotGenParser = pdEl->value; } else { /* No machine spec given, just use the first one. */ if ( parserList.length() == 0 ) error() << "no machine specification to generate graphviz output" << endp; dotGenParser = parserList.head; } GraphDictEl *gdEl = 0; if ( machineName != 0 ) { gdEl = dotGenParser->pd->graphDict.find( machineName ); if ( gdEl == 0 ) error() << "machine definition/instantiation not found" << endp; } else { /* We are using the whole machine spec. Need to make sure there * are instances in the spec. */ if ( dotGenParser->pd->instanceList.length() == 0 ) error() << "no machine instantiations to generate graphviz output" << endp; } dotGenParser->pd->prepareMachineGen( gdEl ); } else { /* No machine spec or machine name given. Generate everything. */ for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) { ParseData *pd = parser->value->pd; if ( pd->instanceList.length() > 0 ) pd->prepareMachineGen( 0 ); } } } void InputData::generateReduced() { if ( generateDot ) dotGenParser->pd->generateReduced( *this ); else { for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) { ParseData *pd = parser->value->pd; if ( pd->instanceList.length() > 0 ) pd->generateReduced( *this ); } } } /* Send eof to all parsers. */ void InputData::terminateAllParsers( ) { /* FIXME: a proper token is needed here. Suppose we should use the * location of EOF in the last file that the parser was referenced in. */ InputLoc loc; loc.fileName = ""; loc.line = 0; loc.col = 0; for ( ParserDict::Iter pdel = parserDict; pdel.lte(); pdel++ ) pdel->value->token( loc, Parser_tk_eof, 0, 0 ); } void InputData::verifyWritesHaveData() { if ( !generateXML && !generateDot ) { for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ ) { if ( ii->type == InputItem::Write ) { if ( ii->pd->cgd == 0 ) error( ii->loc ) << "no machine instantiations to write" << endl; } } } } void InputData::writeOutput() { if ( generateXML ) writeXML( *outStream ); else if ( generateDot ) static_cast(dotGenParser->pd->cgd)->writeDotFile(); else { bool hostLineDirective = true; for ( InputItemList::Iter ii = inputItems; ii.lte(); ii++ ) { if ( ii->type == InputItem::Write ) { CodeGenData *cgd = ii->pd->cgd; ::keyOps = &cgd->thisKeyOps; hostLineDirective = cgd->writeStatement( ii->loc, ii->writeArgs.length()-1, ii->writeArgs.data ); } else { if ( hostLineDirective ) { /* Write statements can turn off host line directives for * host sections that follow them. */ *outStream << '\n'; lineDirective( *outStream, inputFileName, ii->loc.line ); } *outStream << ii->data.str(); hostLineDirective = true; } } } } ragel-6.10/ragel/gofflat.cpp0000664000175000017500000002143013065111230012665 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "gofflat.h" #include "redfsm.h" #include "gendata.h" using std::endl; std::ostream &GoFFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &GoFFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &GoFFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &GoFFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFFlatCodeGen::TO_STATE_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFFlatCodeGen::FROM_STATE_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoFFlatCodeGen::EOF_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFFlatCodeGen::ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); } } genLineDirective( out ); return out; } void GoFFlatCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << endl; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << endl; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << endl; } STATE_IDS(); } void GoFFlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {" << endl << " var _slen " << INT() << endl; if ( redFsm->anyRegCurStateRef() ) out << " var _ps " << INT() << endl; out << " var _trans " << INT() << endl; if ( redFsm->anyConditions() ) out << " var _cond " << INT() << endl; out << " var _keys " << INT() << endl << " var _inds " << INT() << endl; if ( redFsm->anyConditions() ) { out << " var _conds " << INT() << endl << " var _widec " << WIDE_ALPH_TYPE() << endl; } if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " == " << PE() << " {" << endl << " goto _test_eof" << endl << " }" << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } out << "_resume:" << endl; if ( redFsm->anyFromStateActions() ) { out << " switch " << FSA() << "[" << vCS() << "] {" << endl; FROM_STATE_ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) out << "_eof_trans:" << endl; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << endl; out << " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl << endl; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] == 0 {" << endl << " goto _again" << endl << " }" << endl << endl << " switch " << TA() << "[_trans] {" << endl; ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:" << endl; if ( redFsm->anyToStateActions() ) { out << " switch " << TSA() << "[" << vCS() << "] {" << endl; TO_STATE_ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } if ( !noEnd ) { out << " if " << P() << "++; " << P() << " != " << PE() << " {" " goto _resume" << endl << " }" << endl; } else { out << " " << P() << "++" << endl << " goto _resume" << endl; } if ( testEofUsed ) out << " _test_eof: {}" << endl; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << " {" << endl; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0 {" << endl << " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl << " goto _eof_trans" << endl << " }" << endl; } if ( redFsm->anyEofActions() ) { out << " switch " << EA() << "[" << vCS() << "] {" << endl; EOF_ACTION_SWITCH(2); out << " }" << endl; } out << " }" << endl << endl; } if ( outLabelUsed ) out << " _out: {}" << endl; out << " }" << endl; } ragel-6.10/ragel/goflat.h0000664000175000017500000000431013065111230012162 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOFLAT_H #define _GOFLAT_H #include #include "gotablish.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; /* * GoFlatCodeGen */ class GoFlatCodeGen : public GoTablishCodeGen { public: GoFlatCodeGen( ostream &out ) : GoTablishCodeGen(out) {} virtual ~GoFlatCodeGen() { } protected: std::ostream &TO_STATE_ACTION_SWITCH( int level ); std::ostream &FROM_STATE_ACTION_SWITCH( int level ); std::ostream &EOF_ACTION_SWITCH( int level ); std::ostream &ACTION_SWITCH( int level ); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &FLAT_INDEX_OFFSET(); std::ostream &KEY_SPANS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); void LOCATE_TRANS(); std::ostream &COND_INDEX_OFFSET(); void COND_TRANSLATE(); std::ostream &CONDS(); std::ostream &COND_KEYS(); std::ostream &COND_KEY_SPANS(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/gofgoto.h0000664000175000017500000000305713065111230012361 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOFGOTO_H #define _GOFGOTO_H #include #include "gogoto.h" /* Forwards. */ struct CodeGenData; class GoFGotoCodeGen : public GoGotoCodeGen { public: GoFGotoCodeGen( ostream &out ) : GoGotoCodeGen(out) {} std::ostream &EXEC_ACTIONS(); std::ostream &TO_STATE_ACTION_SWITCH( int level ); std::ostream &FROM_STATE_ACTION_SWITCH( int level ); std::ostream &FINISH_CASES(); std::ostream &EOF_ACTION_SWITCH( int level ); unsigned int TO_STATE_ACTION( RedStateAp *state ); unsigned int FROM_STATE_ACTION( RedStateAp *state ); unsigned int EOF_ACTION( RedStateAp *state ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/gogoto.h0000664000175000017500000000475613065111230012222 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOGOTO_H #define _GOGOTO_H #include #include "gotablish.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; struct GenStateCond; /* * Goto driven fsm. */ class GoGotoCodeGen : public GoTablishCodeGen { public: GoGotoCodeGen( ostream &out ) : GoTablishCodeGen(out) {} protected: std::ostream &TO_STATE_ACTION_SWITCH( int level ); std::ostream &FROM_STATE_ACTION_SWITCH( int level ); std::ostream &EOF_ACTION_SWITCH( int level ); std::ostream &ACTION_SWITCH( int level ); std::ostream &STATE_GOTOS( int level ); std::ostream &TRANSITIONS(); std::ostream &EXEC_FUNCS(); std::ostream &FINISH_CASES(); virtual unsigned int TO_STATE_ACTION( RedStateAp *state ); virtual unsigned int FROM_STATE_ACTION( RedStateAp *state ); virtual unsigned int EOF_ACTION( RedStateAp *state ); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); void COND_TRANSLATE( GenStateCond *stateCond, int level ); void emitCondBSearch( RedStateAp *state, int level, int low, int high ); void STATE_CONDS( RedStateAp *state, bool genDefault ); virtual std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); virtual int TRANS_NR( RedTransAp *trans ); void emitSingleSwitch( RedStateAp *state, int level ); void emitRangeBSearch( RedStateAp *state, int level, int low, int high ); /* Called from STATE_GOTOS just before writing the gotos */ virtual void GOTO_HEADER( RedStateAp *state, int level ); virtual void STATE_GOTO_ERROR( int level ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/csipgoto.cpp0000664000175000017500000002667013065111230013105 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "csipgoto.h" #include "redfsm.h" #include "gendata.h" #include "bstmap.h" bool CSharpIpGotoCodeGen::useAgainLabel() { return redFsm->anyRegActionRets() || redFsm->anyRegActionByValControl() || redFsm->anyRegNextStmt(); } void CSharpIpGotoCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{" << CTRL_FLOW() << "goto st" << gotoDest << ";}"; } void CSharpIpGotoCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << targState << "; " << CTRL_FLOW() << "goto st" << callDest << ";}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpIpGotoCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << targState << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << "goto _again;}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpIpGotoCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];"; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "}"; } ret << CTRL_FLOW() << "goto _again;}"; } void CSharpIpGotoCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{" << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << "goto _again;}"; } void CSharpIpGotoCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void CSharpIpGotoCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void CSharpIpGotoCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void CSharpIpGotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << targState; } void CSharpIpGotoCodeGen::BREAK( ostream &ret, int targState ) { /* FIXME: If this code generator is made active then BREAK generation * needs to check csForced. */ outLabelUsed = true; ret << "{" << P() << "++; " << vCS() << " = " << targState << "; " << CTRL_FLOW() << "goto _out;}"; } bool CSharpIpGotoCodeGen::IN_TRANS_ACTIONS( RedStateAp *state ) { bool anyWritten = false; /* Emit any transitions that have actions and that go to this state. */ for ( int it = 0; it < state->numInTrans; it++ ) { RedTransAp *trans = state->inTrans[it]; if ( trans->action != 0 && trans->labelNeeded ) { /* Remember that we wrote an action so we know to write the * line directive for going back to the output. */ anyWritten = true; /* Write the label for the transition so it can be jumped to. */ out << "tr" << trans->id << ":\n"; /* If the action contains a next, then we must preload the current * state since the action may or may not set it. */ if ( trans->action->anyNextStmt() ) out << " " << vCS() << " = " << trans->targ->id << ";\n"; /* Write each action in the list. */ for ( GenActionTable::Iter item = trans->action->key; item.lte(); item++ ) ACTION( out, item->value, trans->targ->id, false ); /* If the action contains a next then we need to reload, otherwise * jump directly to the target state. */ if ( trans->action->anyNextStmt() ) out << "\tgoto _again;\n"; else out << "\tgoto st" << trans->targ->id << ";\n"; } } return anyWritten; } /* Called from GotoCodeGen::STATE_GOTOS just before writing the gotos for each * state. */ void CSharpIpGotoCodeGen::GOTO_HEADER( RedStateAp *state ) { bool anyWritten = IN_TRANS_ACTIONS( state ); if ( state->labelNeeded ) out << "st" << state->id << ":\n"; if ( state->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->toStateAction->key; item.lte(); item++ ) ACTION( out, item->value, state->id, false ); } /* Advance and test buffer pos. */ if ( state->labelNeeded ) { if ( !noEnd ) { out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _test_eof" << state->id << ";\n"; } else { out << " " << P() << " += 1;\n"; } } /* Give the state a switch case. */ out << "case " << state->id << ":\n"; if ( state->fromStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->fromStateAction->key; item.lte(); item++ ) ACTION( out, item->value, state->id, false ); } if ( anyWritten ) genLineDirective( out ); /* Record the prev state if necessary. */ if ( state->anyRegCurStateRef() ) out << " _ps = " << state->id << ";\n"; } void CSharpIpGotoCodeGen::STATE_GOTO_ERROR() { /* In the error state we need to emit some stuff that usually goes into * the header. */ RedStateAp *state = redFsm->errState; bool anyWritten = IN_TRANS_ACTIONS( state ); /* No case label needed since we don't switch on the error state. */ if ( anyWritten ) genLineDirective( out ); if ( state->labelNeeded ) out << "st" << state->id << ":\n"; /* Break out here. */ outLabelUsed = true; out << vCS() << " = " << state->id << ";\n"; out << " goto _out;\n"; } /* Emit the goto to take for a given transition. */ std::ostream &CSharpIpGotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { if ( trans->action != 0 ) { /* Go to the transition which will go to the state. */ out << TABS(level) << "goto tr" << trans->id << ";"; } else { /* Go directly to the target state. */ out << TABS(level) << "goto st" << trans->targ->id << ";"; } return out; } std::ostream &CSharpIpGotoCodeGen::EXIT_STATES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->outNeeded ) { testEofUsed = true; out << " _test_eof" << st->id << ": " << vCS() << " = " << st->id << "; goto _test_eof; \n"; } } return out; } std::ostream &CSharpIpGotoCodeGen::AGAIN_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { out << " case " << st->id << ": goto st" << st->id << ";\n"; } return out; } std::ostream &CSharpIpGotoCodeGen::FINISH_CASES() { bool anyWritten = false; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofAction != 0 ) { if ( st->eofAction->eofRefs == 0 ) st->eofAction->eofRefs = new IntSet; st->eofAction->eofRefs->insert( st->id ); } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " case " << st->id << ": goto tr" << st->eofTrans->id << ";\n"; } for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { if ( act->eofRefs != 0 ) { for ( IntSet::Iter pst = *act->eofRefs; pst.lte(); pst++ ) out << " case " << *pst << ": \n"; /* Remember that we wrote a trans so we know to write the * line directive for going back to the output. */ anyWritten = true; /* Write each action in the eof action list. */ for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) ACTION( out, item->value, STATE_ERR_STATE, true ); out << "\tbreak;\n"; } } if ( anyWritten ) genLineDirective( out ); return out; } void CSharpIpGotoCodeGen::setLabelsNeeded( GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: { /* Mark the target as needing a label. */ item->targState->labelNeeded = true; break; } default: break; } if ( item->children != 0 ) setLabelsNeeded( item->children ); } } /* Set up labelNeeded flag for each state. */ void CSharpIpGotoCodeGen::setLabelsNeeded() { /* If we use the _again label, then we the _again switch, which uses all * labels. */ if ( useAgainLabel() ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = true; } else { /* Do not use all labels by default, init all labelNeeded vars to false. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = false; /* Walk all transitions and set only those that have targs. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* If there is no action with a next statement, then the label will be * needed. */ if ( trans->action == 0 || !trans->action->anyNextStmt() ) trans->targ->labelNeeded = true; /* Need labels for states that have goto or calls in action code * invoked on characters (ie, not from out action code). */ if ( trans->action != 0 ) { /* Loop the actions. */ for ( GenActionTable::Iter act = trans->action->key; act.lte(); act++ ) { /* Get the action and walk it's tree. */ setLabelsNeeded( act->value->inlineList ); } } } } if ( !noEnd ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st != redFsm->errState ) st->outNeeded = st->labelNeeded; } } } void CSharpIpGotoCodeGen::writeData() { STATE_IDS(); } void CSharpIpGotoCodeGen::writeExec() { /* Must set labels immediately before writing because we may depend on the * noend write option. */ setLabelsNeeded(); testEofUsed = false; outLabelUsed = false; out << " {\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( useAgainLabel() ) { out << " goto _resume;\n" "\n" "_again:\n" " switch ( " << vCS() << " ) {\n"; AGAIN_CASES() << " default: break;\n" " }\n" "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } else { out << " " << P() << " += 1;\n"; } out << "_resume:\n"; } out << " switch ( " << vCS() << " )\n {\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " }\n"; EXIT_STATES() << "\n"; if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n" " switch ( " << vCS() << " ) {\n"; FINISH_CASES(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/cstable.h0000664000175000017500000000606513065111230012334 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TABCODEGEN_H #define _TABCODEGEN_H #include #include "cscodegen.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; /* * TabCodeGen */ class CSharpTabCodeGen : virtual public CSharpFsmCodeGen, public CSharpCodeGen { public: CSharpTabCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpCodeGen(out) {} virtual ~CSharpTabCodeGen() { } virtual void writeData(); virtual void writeExec(); protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &COND_KEYS(); std::ostream &COND_SPACES(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &COND_OFFSETS(); std::ostream &KEY_OFFSETS(); std::ostream &INDEX_OFFSETS(); std::ostream &COND_LENS(); std::ostream &SINGLE_LENS(); std::ostream &RANGE_LENS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); std::ostream &TRANS_TARGS_WI(); std::ostream &TRANS_ACTIONS_WI(); void LOCATE_TRANS(); void COND_TRANSLATE(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void calcIndexSize(); void initVarTypes(); string klenType; string keysType; string signedKeysType; string transType; }; #endif ragel-6.10/ragel/cdcodegen.h0000664000175000017500000002023313065111230012623 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDCODEGEN_H #define _CDCODEGEN_H #include #include #include #include "common.h" #include "gendata.h" using std::string; using std::ostream; /* Integer array line length. */ #define IALL 8 /* Forwards. */ struct RedFsmAp; struct RedStateAp; struct CodeGenData; struct GenAction; struct NameInst; struct GenInlineItem; struct GenInlineList; struct RedAction; struct LongestMatch; struct LongestMatchPart; string itoa( int i ); /* * class FsmCodeGen */ class FsmCodeGen : public CodeGenData { public: FsmCodeGen( ostream &out ); virtual ~FsmCodeGen() {} virtual void finishRagelDef(); virtual void writeInit(); virtual void writeStart(); virtual void writeFirstFinal(); virtual void writeError(); protected: string FSM_NAME(); string START_STATE_ID(); ostream &ACTIONS_ARRAY(); string GET_WIDE_KEY(); string GET_WIDE_KEY( RedStateAp *state ); string TABS( int level ); string KEY( Key key ); string WIDE_KEY( RedStateAp *state, Key key ); string LDIR_PATH( char *path ); virtual void ACTION( ostream &ret, GenAction *action, int targState, bool inFinish, bool csForced ); void CONDITION( ostream &ret, GenAction *condition ); string ALPH_TYPE(); string WIDE_ALPH_TYPE(); string ARRAY_TYPE( unsigned long maxVal ); bool isAlphTypeSigned(); bool isWideAlphTypeSigned(); virtual string ARR_OFF( string ptr, string offset ) = 0; virtual string CAST( string type ) = 0; virtual string UINT() = 0; virtual string NULL_ITEM() = 0; virtual string POINTER() = 0; virtual string GET_KEY(); virtual ostream &SWITCH_DEFAULT() = 0; string P(); string PE(); string vEOF(); string ACCESS(); string vCS(); string STACK(); string TOP(); string TOKSTART(); string TOKEND(); string ACT(); string DATA_PREFIX(); string PM() { return "_" + DATA_PREFIX() + "partition_map"; } string C() { return "_" + DATA_PREFIX() + "cond_spaces"; } string CK() { return "_" + DATA_PREFIX() + "cond_keys"; } string K() { return "_" + DATA_PREFIX() + "trans_keys"; } string I() { return "_" + DATA_PREFIX() + "indicies"; } string CO() { return "_" + DATA_PREFIX() + "cond_offsets"; } string KO() { return "_" + DATA_PREFIX() + "key_offsets"; } string IO() { return "_" + DATA_PREFIX() + "index_offsets"; } string CL() { return "_" + DATA_PREFIX() + "cond_lengths"; } string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } string ET() { return "_" + DATA_PREFIX() + "eof_trans"; } string SP() { return "_" + DATA_PREFIX() + "key_spans"; } string CSP() { return "_" + DATA_PREFIX() + "cond_key_spans"; } string START() { return DATA_PREFIX() + "start"; } string ERROR() { return DATA_PREFIX() + "error"; } string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; } string CTXDATA() { return DATA_PREFIX() + "ctxdata"; } void EOF_CHECK( ostream &ret ); void INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish, bool csForced ); virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ) = 0; virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ) = 0; virtual void NEXT( ostream &ret, int nextDest, bool inFinish ) = 0; virtual void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; virtual void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; virtual void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) = 0; virtual void RET( ostream &ret, bool inFinish ) = 0; virtual void BREAK( ostream &ret, int targState, bool csForced ) = 0; virtual void CURS( ostream &ret, bool inFinish ) = 0; virtual void TARGS( ostream &ret, bool inFinish, int targState ) = 0; void EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish, bool csForced ); void SET_ACT( ostream &ret, GenInlineItem *item ); void INIT_TOKSTART( ostream &ret, GenInlineItem *item ); void INIT_ACT( ostream &ret, GenInlineItem *item ); void SET_TOKSTART( ostream &ret, GenInlineItem *item ); void SET_TOKEND( ostream &ret, GenInlineItem *item ); void GET_TOKEND( ostream &ret, GenInlineItem *item ); virtual void SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); void STATE_IDS(); string ERROR_STATE(); string FIRST_FINAL_STATE(); virtual string PTR_CONST() = 0; virtual string PTR_CONST_END() = 0; virtual ostream &OPEN_ARRAY( string type, string name ) = 0; virtual ostream &CLOSE_ARRAY() = 0; virtual ostream &STATIC_VAR( string type, string name ) = 0; virtual string CTRL_FLOW() = 0; ostream &source_warning(const InputLoc &loc); ostream &source_error(const InputLoc &loc); unsigned int arrayTypeSize( unsigned long maxVal ); bool outLabelUsed; bool testEofUsed; bool againLabelUsed; bool useIndicies; void genLineDirective( ostream &out ); public: /* Determine if we should use indicies. */ virtual void calcIndexSize() {} }; class CCodeGen : virtual public FsmCodeGen { public: CCodeGen( ostream &out ) : FsmCodeGen(out) {} virtual string NULL_ITEM(); virtual string POINTER(); virtual ostream &SWITCH_DEFAULT(); virtual ostream &OPEN_ARRAY( string type, string name ); virtual ostream &CLOSE_ARRAY(); virtual ostream &STATIC_VAR( string type, string name ); virtual string ARR_OFF( string ptr, string offset ); virtual string CAST( string type ); virtual string UINT(); virtual string PTR_CONST(); virtual string PTR_CONST_END(); virtual string CTRL_FLOW(); virtual void writeExports(); }; class DCodeGen : virtual public FsmCodeGen { public: DCodeGen( ostream &out ) : FsmCodeGen(out) {} virtual string NULL_ITEM(); virtual string POINTER(); virtual ostream &SWITCH_DEFAULT(); virtual ostream &OPEN_ARRAY( string type, string name ); virtual ostream &CLOSE_ARRAY(); virtual ostream &STATIC_VAR( string type, string name ); virtual string ARR_OFF( string ptr, string offset ); virtual string CAST( string type ); virtual string UINT(); virtual string PTR_CONST(); virtual string PTR_CONST_END(); virtual string CTRL_FLOW(); virtual void writeExports(); }; class D2CodeGen : virtual public FsmCodeGen { public: D2CodeGen( ostream &out ) : FsmCodeGen(out) {} virtual string NULL_ITEM(); virtual string POINTER(); virtual ostream &SWITCH_DEFAULT(); virtual ostream &OPEN_ARRAY( string type, string name ); virtual ostream &CLOSE_ARRAY(); virtual ostream &STATIC_VAR( string type, string name ); virtual string ARR_OFF( string ptr, string offset ); virtual string CAST( string type ); virtual string UINT(); virtual string PTR_CONST(); virtual string PTR_CONST_END(); virtual string CTRL_FLOW(); virtual void writeExports(); virtual void SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ); virtual void ACTION( ostream &ret, GenAction *action, int targState, bool inFinish, bool csForced ); }; #endif ragel-6.10/ragel/config.h.in0000664000175000017500000000116713065122657012606 00000000000000/* ragel/config.h.in. Generated from configure.ac by autoheader. */ /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Version number of package */ #undef VERSION ragel-6.10/ragel/gendata.h0000664000175000017500000001252313065111230012316 00000000000000/* * Copyright 2005-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GENDATA_H #define _GENDATA_H #include #include "config.h" #include "redfsm.h" #include "common.h" using std::ostream; extern bool generateDot; struct NameInst; typedef DList GenActionList; typedef unsigned long ulong; extern int gblErrorCount; struct CodeGenData; typedef AvlMap CodeGenMap; typedef AvlMapEl CodeGenMapEl; void cdLineDirective( ostream &out, const char *fileName, int line ); void javaLineDirective( ostream &out, const char *fileName, int line ); void goLineDirective( ostream &out, const char *fileName, int line ); void rubyLineDirective( ostream &out, const char *fileName, int line ); void csharpLineDirective( ostream &out, const char *fileName, int line ); void ocamlLineDirective( ostream &out, const char *fileName, int line ); void genLineDirective( ostream &out ); void lineDirective( ostream &out, const char *fileName, int line ); string itoa( int i ); /*********************************/ struct CodeGenData { /* * The interface to the code generator. */ virtual void finishRagelDef() {} /* These are invoked by the corresponding write statements. */ virtual void writeData() {}; virtual void writeInit() {}; virtual void writeExec() {}; virtual void writeExports() {}; virtual void writeStart() {}; virtual void writeFirstFinal() {}; virtual void writeError() {}; /* This can also be overwridden to modify the processing of write * statements. */ virtual bool writeStatement( InputLoc &loc, int nargs, char **args ); /********************/ CodeGenData( ostream &out ); virtual ~CodeGenData() {} /* * Collecting the machine. */ const char *sourceFileName; const char *fsmName; ostream &out; RedFsmAp *redFsm; GenAction *allActions; RedAction *allActionTables; Condition *allConditions; GenCondSpace *allCondSpaces; RedStateAp *allStates; NameInst **nameIndex; int startState; int errState; GenActionList actionList; ConditionList conditionList; CondSpaceList condSpaceList; GenInlineList *getKeyExpr; GenInlineList *accessExpr; GenInlineList *prePushExpr; GenInlineList *postPopExpr; /* Overriding variables. */ GenInlineList *pExpr; GenInlineList *peExpr; GenInlineList *eofExpr; GenInlineList *csExpr; GenInlineList *topExpr; GenInlineList *stackExpr; GenInlineList *actExpr; GenInlineList *tokstartExpr; GenInlineList *tokendExpr; GenInlineList *dataExpr; KeyOps thisKeyOps; bool wantComplete; EntryIdVect entryPointIds; EntryNameVect entryPointNames; bool hasLongestMatch; ExportList exportList; /* Write options. */ bool noEnd; bool noPrefix; bool noFinal; bool noError; bool noEntry; bool noCS; void createMachine(); void initActionList( unsigned long length ); void newAction( int anum, const char *name, const InputLoc &loc, GenInlineList *inlineList ); void initActionTableList( unsigned long length ); void initStateList( unsigned long length ); void setStartState( unsigned long startState ); void setErrorState( unsigned long errState ); void addEntryPoint( char *name, unsigned long entryState ); void setId( int snum, int id ); void setFinal( int snum ); void initTransList( int snum, unsigned long length ); void newTrans( int snum, int tnum, Key lowKey, Key highKey, long targ, long act ); void finishTransList( int snum ); void setStateActions( int snum, long toStateAction, long fromStateAction, long eofAction ); void setEofTrans( int snum, long targ, long eofAction ); void setForcedErrorState() { redFsm->forcedErrorState = true; } void initCondSpaceList( ulong length ); void condSpaceItem( int cnum, long condActionId ); void newCondSpace( int cnum, int condSpaceId, Key baseKey ); void initStateCondList( int snum, ulong length ); void addStateCond( int snum, Key lowKey, Key highKey, long condNum ); GenCondSpace *findCondSpace( Key lowKey, Key highKey ); Condition *findCondition( Key key ); bool setAlphType( const char *data ); void resolveTargetStates( GenInlineList *inlineList ); Key findMaxKey(); /* Gather various info on the machine. */ void analyzeActionList( RedAction *redAct, GenInlineList *inlineList ); void analyzeAction( GenAction *act, GenInlineList *inlineList ); void findFinalActionRefs(); void analyzeMachine(); void closeMachine(); void setValueLimits(); void assignActionIds(); ostream &source_warning( const InputLoc &loc ); ostream &source_error( const InputLoc &loc ); void write_option_error( InputLoc &loc, char *arg ); }; CodeGenData *makeCodeGen( const char *sourceFileName, const char *fsmName, ostream &out ); #endif ragel-6.10/ragel/fsmattach.cpp0000664000175000017500000003323213065111230013220 00000000000000/* * Copyright 2001 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "fsmgraph.h" #include using namespace std; /* Insert a transition into an inlist. The head must be supplied. */ void FsmAp::attachToInList( StateAp *from, StateAp *to, TransAp *&head, TransAp *trans ) { trans->ilnext = head; trans->ilprev = 0; /* If in trans list is not empty, set the head->prev to trans. */ if ( head != 0 ) head->ilprev = trans; /* Now insert ourselves at the front of the list. */ head = trans; /* Keep track of foreign transitions for from and to. */ if ( from != to ) { if ( misfitAccounting ) { /* If the number of foreign in transitions is about to go up to 1 then * move it from the misfit list to the main list. */ if ( to->foreignInTrans == 0 ) stateList.append( misfitList.detach( to ) ); } to->foreignInTrans += 1; } }; /* Detach a transition from an inlist. The head of the inlist must be supplied. */ void FsmAp::detachFromInList( StateAp *from, StateAp *to, TransAp *&head, TransAp *trans ) { /* Detach in the inTransList. */ if ( trans->ilprev == 0 ) head = trans->ilnext; else trans->ilprev->ilnext = trans->ilnext; if ( trans->ilnext != 0 ) trans->ilnext->ilprev = trans->ilprev; /* Keep track of foreign transitions for from and to. */ if ( from != to ) { to->foreignInTrans -= 1; if ( misfitAccounting ) { /* If the number of foreign in transitions goes down to 0 then move it * from the main list to the misfit list. */ if ( to->foreignInTrans == 0 ) misfitList.append( stateList.detach( to ) ); } } } /* Attach states on the default transition, range list or on out/in list key. * First makes a new transition. If there is already a transition out from * fromState on the default, then will assertion fail. */ TransAp *FsmAp::attachNewTrans( StateAp *from, StateAp *to, Key lowKey, Key highKey ) { /* Make the new transition. */ TransAp *retVal = new TransAp(); /* The transition is now attached. Remember the parties involved. */ retVal->fromState = from; retVal->toState = to; /* Make the entry in the out list for the transitions. */ from->outList.append( retVal ); /* Set the the keys of the new trans. */ retVal->lowKey = lowKey; retVal->highKey = highKey; /* Attach using inList as the head pointer. */ if ( to != 0 ) attachToInList( from, to, to->inList.head, retVal ); return retVal; } /* Attach for range lists or for the default transition. This attach should * be used when a transition already is allocated and must be attached to a * target state. Does not handle adding the transition into the out list. */ void FsmAp::attachTrans( StateAp *from, StateAp *to, TransAp *trans ) { assert( trans->fromState == 0 && trans->toState == 0 ); trans->fromState = from; trans->toState = to; if ( to != 0 ) { /* Attach using the inList pointer as the head pointer. */ attachToInList( from, to, to->inList.head, trans ); } } /* Redirect a transition away from error and towards some state. This is just * like attachTrans except it requires fromState to be set and does not touch * it. */ void FsmAp::redirectErrorTrans( StateAp *from, StateAp *to, TransAp *trans ) { assert( trans->fromState != 0 && trans->toState == 0 ); trans->toState = to; if ( to != 0 ) { /* Attach using the inList pointer as the head pointer. */ attachToInList( from, to, to->inList.head, trans ); } } /* Detach for out/in lists or for default transition. */ void FsmAp::detachTrans( StateAp *from, StateAp *to, TransAp *trans ) { assert( trans->fromState == from && trans->toState == to ); trans->fromState = 0; trans->toState = 0; if ( to != 0 ) { /* Detach using to's inList pointer as the head. */ detachFromInList( from, to, to->inList.head, trans ); } } /* Detach a state from the graph. Detaches and deletes transitions in and out * of the state. Empties inList and outList. Removes the state from the final * state set. A detached state becomes useless and should be deleted. */ void FsmAp::detachState( StateAp *state ) { /* Detach the in transitions from the inList list of transitions. */ while ( state->inList.head != 0 ) { /* Get pointers to the trans and the state. */ TransAp *trans = state->inList.head; StateAp *fromState = trans->fromState; /* Detach the transitions from the source state. */ detachTrans( fromState, state, trans ); /* Ok to delete the transition. */ fromState->outList.detach( trans ); delete trans; } /* Remove the entry points in on the machine. */ while ( state->entryIds.length() > 0 ) unsetEntry( state->entryIds[0], state ); /* Detach out range transitions. */ for ( TransList::Iter trans = state->outList; trans.lte(); ) { TransList::Iter next = trans.next(); detachTrans( state, trans->toState, trans ); delete trans; trans = next; } /* Delete all of the out range pointers. */ state->outList.abandon(); /* Unset final stateness before detaching from graph. */ if ( state->stateBits & STB_ISFINAL ) finStateSet.remove( state ); } /* Duplicate a transition. Makes a new transition that is attached to the same * dest as srcTrans. The new transition has functions and priority taken from * srcTrans. Used for merging a transition in to a free spot. The trans can * just be dropped in. It does not conflict with an existing trans and need * not be crossed. Returns the new transition. */ TransAp *FsmAp::dupTrans( StateAp *from, TransAp *srcTrans ) { /* Make a new transition. */ TransAp *newTrans = new TransAp(); /* We can attach the transition, one does not exist. */ attachTrans( from, srcTrans->toState, newTrans ); /* Call the user callback to add in the original source transition. */ addInTrans( newTrans, srcTrans ); return newTrans; } /* In crossing, src trans and dest trans both go to existing states. Make one * state from the sets of states that src and dest trans go to. */ TransAp *FsmAp::fsmAttachStates( MergeData &md, StateAp *from, TransAp *destTrans, TransAp *srcTrans ) { /* The priorities are equal. We must merge the transitions. Does the * existing trans go to the state we are to attach to? ie, are we to * simply double up the transition? */ StateAp *toState = srcTrans->toState; StateAp *existingState = destTrans->toState; if ( existingState == toState ) { /* The transition is a double up to the same state. Copy the src * trans into itself. We don't need to merge in the from out trans * data, that was done already. */ addInTrans( destTrans, srcTrans ); } else { /* The trans is not a double up. Dest trans cannot be the same as src * trans. Set up the state set. */ StateSet stateSet; /* We go to all the states the existing trans goes to, plus... */ if ( existingState->stateDictEl == 0 ) stateSet.insert( existingState ); else stateSet.insert( existingState->stateDictEl->stateSet ); /* ... all the states that we have been told to go to. */ if ( toState->stateDictEl == 0 ) stateSet.insert( toState ); else stateSet.insert( toState->stateDictEl->stateSet ); /* Look for the state. If it is not there already, make it. */ StateDictEl *lastFound; if ( md.stateDict.insert( stateSet, &lastFound ) ) { /* Make a new state representing the combination of states in * stateSet. It gets added to the fill list. This means that we * need to fill in it's transitions sometime in the future. We * don't do that now (ie, do not recurse). */ StateAp *combinState = addState(); /* Link up the dict element and the state. */ lastFound->targState = combinState; combinState->stateDictEl = lastFound; /* Add to the fill list. */ md.fillListAppend( combinState ); } /* Get the state insertted/deleted. */ StateAp *targ = lastFound->targState; /* Detach the state from existing state. */ detachTrans( from, existingState, destTrans ); /* Re-attach to the new target. */ attachTrans( from, targ, destTrans ); /* Add in src trans to the existing transition that we redirected to * the new state. We don't need to merge in the from out trans data, * that was done already. */ addInTrans( destTrans, srcTrans ); } return destTrans; } /* Two transitions are to be crossed, handle the possibility of either going * to the error state. */ TransAp *FsmAp::mergeTrans( MergeData &md, StateAp *from, TransAp *destTrans, TransAp *srcTrans ) { TransAp *retTrans = 0; if ( destTrans->toState == 0 && srcTrans->toState == 0 ) { /* Error added into error. */ addInTrans( destTrans, srcTrans ); retTrans = destTrans; } else if ( destTrans->toState == 0 && srcTrans->toState != 0 ) { /* Non error added into error we need to detach and reattach, */ detachTrans( from, destTrans->toState, destTrans ); attachTrans( from, srcTrans->toState, destTrans ); addInTrans( destTrans, srcTrans ); retTrans = destTrans; } else if ( srcTrans->toState == 0 ) { /* Dest goes somewhere but src doesn't, just add it it in. */ addInTrans( destTrans, srcTrans ); retTrans = destTrans; } else { /* Both go somewhere, run the actual cross. */ retTrans = fsmAttachStates( md, from, destTrans, srcTrans ); } return retTrans; } /* Find the trans with the higher priority. If src is lower priority then dest then * src is ignored. If src is higher priority than dest, then src overwrites dest. If * the priorities are equal, then they are merged. */ TransAp *FsmAp::crossTransitions( MergeData &md, StateAp *from, TransAp *destTrans, TransAp *srcTrans ) { TransAp *retTrans; /* Compare the priority of the dest and src transitions. */ int compareRes = comparePrior( destTrans->priorTable, srcTrans->priorTable ); if ( compareRes < 0 ) { /* Src trans has a higher priority than dest, src overwrites dest. * Detach dest and return a copy of src. */ detachTrans( from, destTrans->toState, destTrans ); retTrans = dupTrans( from, srcTrans ); } else if ( compareRes > 0 ) { /* The dest trans has a higher priority, use dest. */ retTrans = destTrans; } else { /* Src trans and dest trans have the same priority, they must be merged. */ retTrans = mergeTrans( md, from, destTrans, srcTrans ); } /* Return the transition that resulted from the cross. */ return retTrans; } /* Copy the transitions in srcList to the outlist of dest. The srcList should * not be the outList of dest, otherwise you would be copying the contents of * srcList into itself as it's iterated: bad news. */ void FsmAp::outTransCopy( MergeData &md, StateAp *dest, TransAp *srcList ) { /* The destination list. */ TransList destList; /* Set up an iterator to stop at breaks. */ PairIter outPair( dest->outList.head, srcList ); for ( ; !outPair.end(); outPair++ ) { switch ( outPair.userState ) { case RangeInS1: { /* The pair iter is the authority on the keys. It may have needed * to break the dest range. */ TransAp *destTrans = outPair.s1Tel.trans; destTrans->lowKey = outPair.s1Tel.lowKey; destTrans->highKey = outPair.s1Tel.highKey; destList.append( destTrans ); break; } case RangeInS2: { /* Src range may get crossed with dest's default transition. */ TransAp *newTrans = dupTrans( dest, outPair.s2Tel.trans ); /* Set up the transition's keys and append to the dest list. */ newTrans->lowKey = outPair.s2Tel.lowKey; newTrans->highKey = outPair.s2Tel.highKey; destList.append( newTrans ); break; } case RangeOverlap: { /* Exact overlap, cross them. */ TransAp *newTrans = crossTransitions( md, dest, outPair.s1Tel.trans, outPair.s2Tel.trans ); /* Set up the transition's keys and append to the dest list. */ newTrans->lowKey = outPair.s1Tel.lowKey; newTrans->highKey = outPair.s1Tel.highKey; destList.append( newTrans ); break; } case BreakS1: { /* Since we are always writing to the dest trans, the dest needs * to be copied when it is broken. The copy goes into the first * half of the break to "break it off". */ outPair.s1Tel.trans = dupTrans( dest, outPair.s1Tel.trans ); break; } case BreakS2: break; } } /* Abandon the old outList and transfer destList into it. */ dest->outList.transfer( destList ); } /* Move all the transitions that go into src so that they go into dest. */ void FsmAp::inTransMove( StateAp *dest, StateAp *src ) { /* Do not try to move in trans to and from the same state. */ assert( dest != src ); /* If src is the start state, dest becomes the start state. */ if ( src == startState ) { unsetStartState(); setStartState( dest ); } /* For each entry point into, create an entry point into dest, when the * state is detached, the entry points to src will be removed. */ for ( EntryIdSet::Iter enId = src->entryIds; enId.lte(); enId++ ) changeEntry( *enId, dest, src ); /* Move the transitions in inList. */ while ( src->inList.head != 0 ) { /* Get trans and from state. */ TransAp *trans = src->inList.head; StateAp *fromState = trans->fromState; /* Detach from src, reattach to dest. */ detachTrans( fromState, src, trans ); attachTrans( fromState, dest, trans ); } } ragel-6.10/ragel/rubytable.h0000664000175000017500000000703213065111230012703 00000000000000/* * Copyright 2007 Victor Hugo Borja * 2006-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RUBY_TABCODEGEN_H #define _RUBY_TABCODEGEN_H #include #include #include #include "common.h" #include "gendata.h" #include "rubycodegen.h" using std::string; using std::ostream; /* * RubyCodeGen */ class RubyTabCodeGen : public RubyCodeGen { public: RubyTabCodeGen( ostream &out ) : RubyCodeGen(out) {} virtual ~RubyTabCodeGen() {} public: void BREAK( ostream &ret, int targState ); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void RET( ostream &ret, bool inFinish ); void COND_TRANSLATE(); void LOCATE_TRANS(); virtual void writeExec(); virtual void writeData(); protected: virtual std::ostream &TO_STATE_ACTION_SWITCH(); virtual std::ostream &FROM_STATE_ACTION_SWITCH(); virtual std::ostream &EOF_ACTION_SWITCH(); virtual std::ostream &ACTION_SWITCH(); std::ostream &COND_KEYS(); std::ostream &COND_SPACES(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &COND_OFFSETS(); std::ostream &KEY_OFFSETS(); std::ostream &INDEX_OFFSETS(); std::ostream &COND_LENS(); std::ostream &SINGLE_LENS(); std::ostream &RANGE_LENS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); std::ostream &TRANS_TARGS_WI(); std::ostream &TRANS_ACTIONS_WI(); void NEXT( ostream &ret, int nextDest, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); virtual int TO_STATE_ACTION( RedStateAp *state ); virtual int FROM_STATE_ACTION( RedStateAp *state ); virtual int EOF_ACTION( RedStateAp *state ); private: string array_type; string array_name; public: void EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void EXECTE( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void SET_ACT( ostream &ret, GenInlineItem *item ); void INIT_TOKSTART( ostream &ret, GenInlineItem *item ); void INIT_ACT( ostream &ret, GenInlineItem *item ); void SET_TOKSTART( ostream &ret, GenInlineItem *item ); void SET_TOKEND( ostream &ret, GenInlineItem *item ); void GET_TOKEND( ostream &ret, GenInlineItem *item ); void SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish ); }; #endif /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/pcheck.h0000664000175000017500000000300113065111230012137 00000000000000/* * Copyright 2001, 2002 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PCHECK_H #define _PCHECK_H class ParamCheck { public: ParamCheck( const char *paramSpec, int argc, const char **argv); bool check(); const char *paramArg; /* The argument to the parameter. */ char parameter; /* The parameter matched. */ enum { match, invalid, noparam } state; const char *argOffset; /* If we are reading params inside an * arg this points to the offset. */ const char *curArg; /* Pointer to the current arg. */ int iCurArg; /* Index to the current arg. */ private: const char *paramSpec; /* Parameter spec supplied by the coder. */ int argc; /* Arguement data from the command line. */ const char **argv; }; #endif ragel-6.10/ragel/cdflat.h0000664000175000017500000000641313065111230012151 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDFLAT_H #define _CDFLAT_H #include #include "cdcodegen.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; /* * FlatCodeGen */ class FlatCodeGen : virtual public FsmCodeGen { public: FlatCodeGen( ostream &out ) : FsmCodeGen(out) {} virtual ~FlatCodeGen() { } protected: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &FLAT_INDEX_OFFSET(); std::ostream &KEY_SPANS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); void LOCATE_TRANS(); std::ostream &COND_INDEX_OFFSET(); void COND_TRANSLATE(); std::ostream &CONDS(); std::ostream &COND_KEYS(); std::ostream &COND_KEY_SPANS(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState, bool csForced ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; /* * CFlatCodeGen */ struct CFlatCodeGen : public FlatCodeGen, public CCodeGen { CFlatCodeGen( ostream &out ) : FsmCodeGen(out), FlatCodeGen(out), CCodeGen(out) {} }; /* * DFlatCodeGen */ struct DFlatCodeGen : public FlatCodeGen, public DCodeGen { DFlatCodeGen( ostream &out ) : FsmCodeGen(out), FlatCodeGen(out), DCodeGen(out) {} }; /* * D2FlatCodeGen */ struct D2FlatCodeGen : public FlatCodeGen, public D2CodeGen { D2FlatCodeGen( ostream &out ) : FsmCodeGen(out), FlatCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/redfsm.h0000664000175000017500000003037513065111230012200 00000000000000/* * Copyright 2001-2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _REDFSM_H #define _REDFSM_H #include #include #include #include "config.h" #include "common.h" #include "vector.h" #include "dlist.h" #include "compare.h" #include "bstmap.h" #include "bstset.h" #include "avlmap.h" #include "avltree.h" #include "avlbasic.h" #include "mergesort.h" #include "sbstmap.h" #include "sbstset.h" #include "sbsttable.h" #define TRANS_ERR_TRANS 0 #define STATE_ERR_STATE 0 #define FUNC_NO_FUNC 0 using std::string; struct RedStateAp; struct GenInlineList; struct GenAction; /* * Inline code tree */ struct GenInlineItem { enum Type { Text, Goto, Call, Next, GotoExpr, CallExpr, NextExpr, Ret, PChar, Char, Hold, Exec, Curs, Targs, Entry, LmSwitch, LmSetActId, LmSetTokEnd, LmGetTokEnd, LmInitTokStart, LmInitAct, LmSetTokStart, SubAction, Break }; GenInlineItem( const InputLoc &loc, Type type ) : loc(loc), data(0), targId(0), targState(0), lmId(0), children(0), offset(0), type(type) { } InputLoc loc; char *data; int targId; RedStateAp *targState; int lmId; GenInlineList *children; int offset; Type type; GenInlineItem *prev, *next; }; /* Normally this would be atypedef, but that would entail including DList from * ptreetypes, which should be just typedef forwards. */ struct GenInlineList : public DList { }; /* Element in list of actions. Contains the string for the code to exectute. */ struct GenAction : public DListEl { GenAction( ) : name(0), inlineList(0), actionId(0), numTransRefs(0), numToStateRefs(0), numFromStateRefs(0), numEofRefs(0) { } /* Data collected during parse. */ InputLoc loc; const char *name; GenInlineList *inlineList; int actionId; string nameOrLoc(); /* Number of references in the final machine. */ int numRefs() { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; } int numTransRefs; int numToStateRefs; int numFromStateRefs; int numEofRefs; }; /* Forwards. */ struct RedStateAp; struct StateAp; /* Transistion GenAction Element. */ typedef SBstMapEl< int, GenAction* > GenActionTableEl; /* Transition GenAction Table. */ struct GenActionTable : public SBstMap< int, GenAction*, CmpOrd > { void setAction( int ordering, GenAction *action ); void setActions( int *orderings, GenAction **actions, int nActs ); void setActions( const GenActionTable &other ); }; /* Compare of a whole action table element (key & value). */ struct CmpGenActionTableEl { static int compare( const GenActionTableEl &action1, const GenActionTableEl &action2 ) { if ( action1.key < action2.key ) return -1; else if ( action1.key > action2.key ) return 1; else if ( action1.value < action2.value ) return -1; else if ( action1.value > action2.value ) return 1; return 0; } }; /* Compare for GenActionTable. */ typedef CmpSTable< GenActionTableEl, CmpGenActionTableEl > CmpGenActionTable; /* Set of states. */ typedef BstSet RedStateSet; typedef BstSet IntSet; /* Reduced action. */ struct RedAction : public AvlTreeEl { RedAction( ) : key(), eofRefs(0), numTransRefs(0), numToStateRefs(0), numFromStateRefs(0), numEofRefs(0), bAnyNextStmt(false), bAnyCurStateRef(false), bAnyBreakStmt(false) { } const GenActionTable &getKey() { return key; } GenActionTable key; int actListId; int location; IntSet *eofRefs; /* Number of references in the final machine. */ int numRefs() { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; } int numTransRefs; int numToStateRefs; int numFromStateRefs; int numEofRefs; bool anyNextStmt() { return bAnyNextStmt; } bool anyCurStateRef() { return bAnyCurStateRef; } bool anyBreakStmt() { return bAnyBreakStmt; } bool bAnyNextStmt; bool bAnyCurStateRef; bool bAnyBreakStmt; }; typedef AvlTree GenActionTableMap; /* Reduced transition. */ struct RedTransAp : public AvlTreeEl { RedTransAp( RedStateAp *targ, RedAction *action, int id ) : targ(targ), action(action), id(id), pos(-1), labelNeeded(true) { } RedStateAp *targ; RedAction *action; int id; int pos; bool partitionBoundary; bool labelNeeded; }; /* Compare of transitions for the final reduction of transitions. Comparison * is on target and the pointer to the shared action table. It is assumed that * when this is used the action tables have been reduced. */ struct CmpRedTransAp { static int compare( const RedTransAp &t1, const RedTransAp &t2 ) { if ( t1.targ < t2.targ ) return -1; else if ( t1.targ > t2.targ ) return 1; else if ( t1.action < t2.action ) return -1; else if ( t1.action > t2.action ) return 1; else return 0; } }; typedef AvlBasic TransApSet; /* Element in out range. */ struct RedTransEl { /* Constructors. */ RedTransEl( Key lowKey, Key highKey, RedTransAp *value ) : lowKey(lowKey), highKey(highKey), value(value) { } Key lowKey, highKey; RedTransAp *value; }; typedef Vector RedTransList; typedef Vector RedStateVect; typedef BstMapEl RedSpanMapEl; typedef BstMap RedSpanMap; /* Compare used by span map sort. Reverse sorts by the span. */ struct CmpRedSpanMapEl { static int compare( const RedSpanMapEl &smel1, const RedSpanMapEl &smel2 ) { if ( smel1.value > smel2.value ) return -1; else if ( smel1.value < smel2.value ) return 1; else return 0; } }; /* Sorting state-span map entries by span. */ typedef MergeSort RedSpanMapSort; /* Set of entry ids that go into this state. */ typedef Vector EntryIdVect; typedef Vector EntryNameVect; typedef Vector< GenAction* > GenCondSet; struct Condition { Condition( ) : key(0), baseKey(0) {} Key key; Key baseKey; GenCondSet condSet; Condition *next, *prev; }; typedef DList ConditionList; struct GenCondSpace { Key baseKey; GenCondSet condSet; int condSpaceId; GenCondSpace *next, *prev; }; typedef DList CondSpaceList; struct GenStateCond { Key lowKey; Key highKey; GenCondSpace *condSpace; GenStateCond *prev, *next; }; typedef DList GenStateCondList; typedef Vector StateCondVect; /* Reduced state. */ struct RedStateAp { RedStateAp() : defTrans(0), condList(0), transList(0), isFinal(false), labelNeeded(false), outNeeded(false), onStateList(false), toStateAction(0), fromStateAction(0), eofAction(0), eofTrans(0), id(0), bAnyRegCurStateRef(false), partitionBoundary(false), inTrans(0), numInTrans(0) { } /* Transitions out. */ RedTransList outSingle; RedTransList outRange; RedTransAp *defTrans; /* For flat conditions. */ Key condLowKey, condHighKey; GenCondSpace **condList; /* For flat keys. */ Key lowKey, highKey; RedTransAp **transList; /* The list of states that transitions from this state go to. */ RedStateVect targStates; bool isFinal; bool labelNeeded; bool outNeeded; bool onStateList; RedAction *toStateAction; RedAction *fromStateAction; RedAction *eofAction; RedTransAp *eofTrans; int id; GenStateCondList stateCondList; StateCondVect stateCondVect; /* Pointers for the list of states. */ RedStateAp *prev, *next; bool anyRegCurStateRef() { return bAnyRegCurStateRef; } bool bAnyRegCurStateRef; int partition; bool partitionBoundary; RedTransAp **inTrans; int numInTrans; }; /* List of states. */ typedef DList RedStateList; /* Set of reduced transitons. Comparison is by pointer. */ typedef BstSet< RedTransAp*, CmpOrd > RedTransSet; /* Next version of the fsm machine. */ struct RedFsmAp { RedFsmAp(); bool forcedErrorState; int nextActionId; int nextTransId; /* Next State Id doubles as the total number of state ids. */ int nextStateId; TransApSet transSet; GenActionTableMap actionMap; RedStateList stateList; RedStateSet entryPoints; RedStateAp *startState; RedStateAp *errState; RedTransAp *errTrans; RedTransAp *errActionTrans; RedStateAp *firstFinState; int numFinStates; int nParts; bool bAnyToStateActions; bool bAnyFromStateActions; bool bAnyRegActions; bool bAnyEofActions; bool bAnyEofTrans; bool bAnyActionGotos; bool bAnyActionCalls; bool bAnyActionRets; bool bAnyActionByValControl; bool bAnyRegActionRets; bool bAnyRegActionByValControl; bool bAnyRegNextStmt; bool bAnyRegCurStateRef; bool bAnyRegBreak; bool bAnyConditions; int maxState; int maxSingleLen; int maxRangeLen; int maxKeyOffset; int maxIndexOffset; int maxIndex; int maxActListId; int maxActionLoc; int maxActArrItem; unsigned long long maxSpan; unsigned long long maxCondSpan; int maxFlatIndexOffset; Key maxKey; int maxCondOffset; int maxCondLen; int maxCondSpaceId; int maxCondIndexOffset; int maxCond; bool anyActions(); bool anyToStateActions() { return bAnyToStateActions; } bool anyFromStateActions() { return bAnyFromStateActions; } bool anyRegActions() { return bAnyRegActions; } bool anyEofActions() { return bAnyEofActions; } bool anyEofTrans() { return bAnyEofTrans; } bool anyActionGotos() { return bAnyActionGotos; } bool anyActionCalls() { return bAnyActionCalls; } bool anyActionRets() { return bAnyActionRets; } bool anyActionByValControl() { return bAnyActionByValControl; } bool anyRegActionRets() { return bAnyRegActionRets; } bool anyRegActionByValControl() { return bAnyRegActionByValControl; } bool anyRegNextStmt() { return bAnyRegNextStmt; } bool anyRegCurStateRef() { return bAnyRegCurStateRef; } bool anyRegBreak() { return bAnyRegBreak; } bool anyConditions() { return bAnyConditions; } /* Is is it possible to extend a range by bumping ranges that span only * one character to the singles array. */ bool canExtend( const RedTransList &list, int pos ); /* Pick single transitions from the ranges. */ void moveTransToSingle( RedStateAp *state ); void chooseSingle(); void makeFlat(); /* Move a selected transition from ranges to default. */ void moveToDefault( RedTransAp *defTrans, RedStateAp *state ); /* Pick a default transition by largest span. */ RedTransAp *chooseDefaultSpan( RedStateAp *state ); void chooseDefaultSpan(); /* Pick a default transition by most number of ranges. */ RedTransAp *chooseDefaultNumRanges( RedStateAp *state ); void chooseDefaultNumRanges(); /* Pick a default transition tailored towards goto driven machine. */ RedTransAp *chooseDefaultGoto( RedStateAp *state ); void chooseDefaultGoto(); /* Ordering states by transition connections. */ void optimizeStateOrdering( RedStateAp *state ); void optimizeStateOrdering(); /* Ordering states by transition connections. */ void depthFirstOrdering( RedStateAp *state ); void depthFirstOrdering(); /* Set state ids. */ void sequentialStateIds(); void sortStateIdsByFinal(); /* Arrange states in by final id. This is a stable sort. */ void sortStatesByFinal(); /* Sorting states by id. */ void sortByStateId(); /* Locating the first final state. This is the final state with the lowest * id. */ void findFirstFinState(); void assignActionLocs(); RedTransAp *getErrorTrans(); RedStateAp *getErrorState(); /* Is every char in the alphabet covered? */ bool alphabetCovered( RedTransList &outRange ); RedTransAp *allocateTrans( RedStateAp *targState, RedAction *actionTable ); void partitionFsm( int nParts ); void setInTrans(); }; #endif ragel-6.10/ragel/rlparse.kh0000664000175000017500000000775513065111230012551 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RLPARSE_H #define _RLPARSE_H #include #include "avltree.h" #include "parsedata.h" /* Import scanner tokens. */ #define IMP_Word 128 #define IMP_Literal 129 #define IMP_UInt 130 #define IMP_Define 131 /* This is used for tracking the include files/machine pairs. */ struct IncludeHistoryItem { IncludeHistoryItem( const char *fileName, const char *sectionName ) : fileName(fileName), sectionName(sectionName) {} const char *fileName; const char *sectionName; }; typedef Vector IncludeHistory; struct Parser { %%{ parser Parser; # General tokens. token TK_Word, TK_Literal, TK_Number, TK_EndSection, TK_UInt, TK_Hex, TK_Word, TK_Literal, TK_DotDot, TK_ColonGt, TK_ColonGtGt, TK_LtColon, TK_Arrow, TK_DoubleArrow, TK_StarStar, TK_ColonEquals, TK_NameSep, TK_BarStar, TK_DashDash; # Conditions. token TK_StartCond, TK_AllCond, TK_LeavingCond; # State embedding actions. token TK_Middle; # Global error actions. token TK_StartGblError, TK_AllGblError, TK_FinalGblError, TK_NotFinalGblError, TK_NotStartGblError, TK_MiddleGblError; # Local error actions. token TK_StartLocalError, TK_AllLocalError, TK_FinalLocalError, TK_NotFinalLocalError, TK_NotStartLocalError, TK_MiddleLocalError; # EOF Action embedding. token TK_StartEOF, TK_AllEOF, TK_FinalEOF, TK_NotFinalEOF, TK_NotStartEOF, TK_MiddleEOF; # To State Actions. token TK_StartToState, TK_AllToState, TK_FinalToState, TK_NotFinalToState, TK_NotStartToState, TK_MiddleToState; # In State Actions. token TK_StartFromState, TK_AllFromState, TK_FinalFromState, TK_NotFinalFromState, TK_NotStartFromState, TK_MiddleFromState; # Regular expression tokens. */ token RE_Slash, RE_SqOpen, RE_SqOpenNeg, RE_SqClose, RE_Dot, RE_Star, RE_Dash, RE_Char; # Tokens specific to inline code. token IL_WhiteSpace, IL_Comment, IL_Literal, IL_Symbol; # Keywords. token KW_Machine, KW_Include, KW_Import, KW_Write, KW_Action, KW_AlphType, KW_Range, KW_GetKey, KW_Include, KW_Write, KW_Machine, KW_InWhen, KW_When, KW_OutWhen, KW_Eof, KW_Err, KW_Lerr, KW_To, KW_From, KW_Export, KW_PrePush, KW_PostPop, KW_Length; # Specials in code blocks. token KW_Break, KW_Exec, KW_Hold, KW_PChar, KW_Char, KW_Goto, KW_Call, KW_Ret, KW_CurState, KW_TargState, KW_Entry, KW_Next, KW_Exec, KW_Variable, KW_Access; }%% %% write instance_data; void init(); int parseLangEl( int type, const Token *token ); Parser( const char *fileName, char *sectionName, InputLoc §ionLoc ) : sectionName(sectionName) { pd = new ParseData( fileName, sectionName, sectionLoc ); exportContext.append( false ); includeHistory.append( IncludeHistoryItem( fileName, sectionName ) ); } int token( InputLoc &loc, int tokId, char *tokstart, int toklen ); void tryMachineDef( InputLoc &loc, char *name, MachineDef *machineDef, bool isInstance ); /* Report an error encountered by the parser. */ ostream &parse_error( int tokId, Token &token ); ParseData *pd; /* The name of the root section, this does not change during an include. */ char *sectionName; NameRef nameRef; NameRefList nameRefList; Vector exportContext; IncludeHistory includeHistory; Parser *prev, *next; }; %% write token_defs; #endif ragel-6.10/ragel/rubytable.cpp0000664000175000017500000006125613065111230013246 00000000000000/* * Copyright 2007 Victor Hugo Borja * 2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "redfsm.h" #include "gendata.h" #include "ragel.h" #include "rubytable.h" using std::ostream; using std::ostringstream; using std::string; using std::cerr; using std::endl; void RubyTabCodeGen::GOTO( ostream &out, int gotoDest, bool inFinish ) { out << " begin\n" " " << vCS() << " = " << gotoDest << "\n" " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; } void RubyTabCodeGen::GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ) { out << " begin\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, 0, inFinish ); out << ")\n"; out << " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; } void RubyTabCodeGen::CALL( ostream &out, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << "+= 1\n" " " << vCS() << " = " << callDest << "\n" " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyTabCodeGen::CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << " += 1\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, targState, inFinish ); out << ")\n"; out << " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyTabCodeGen::RET( ostream &out, bool inFinish ) { out << " begin\n" " " << TOP() << " -= 1\n" " " << vCS() << " = " << STACK() << "[" << TOP() << "]\n"; if ( postPopExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, postPopExpr, 0, false ); out << "end\n"; } out << " _trigger_goto = true\n" " _goto_level = _again\n" " break\n" " end\n"; } void RubyTabCodeGen::BREAK( ostream &out, int targState ) { out << " begin\n" " " << P() << " += 1\n" " _trigger_goto = true\n" " _goto_level = _out\n" " break\n" " end\n"; } void RubyTabCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << "\n" " _keys = " << CO() << "[" << vCS() << "]*2\n" " _klen = " << CL() << "[" << vCS() << "]\n" " if _klen > 0\n" " _lower = _keys\n" " _upper = _keys + (_klen<<1) - 2\n" " loop do\n" " break if _upper < _lower\n" " _mid = _lower + (((_upper-_lower) >> 1) & ~1)\n" " if " << GET_WIDE_KEY() << " < " << CK() << "[_mid]\n" " _upper = _mid - 2\n" " elsif " << GET_WIDE_KEY() << " > " << CK() << "[_mid+1]\n" " _lower = _mid + 2\n" " else\n" " case " << C() << "[" << CO() << "[" << vCS() << "]" " + ((_mid - _keys)>>1)]\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " when " << condSpace->condSpaceId << " then" ; out << " _widec = " << KEY(condSpace->baseKey) << "+ (" << GET_KEY() << " - " << KEY(keyOps->minKey) << ")\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " _widec += " << condValOffset << " if ( "; CONDITION( out, *csi ); out << " )\n"; } } out << " end # case\n" " end\n" " end # loop\n" " end\n"; } void RubyTabCodeGen::LOCATE_TRANS() { out << " _keys = " << KO() << "[" << vCS() << "]\n" " _trans = " << IO() << "[" << vCS() << "]\n" " _klen = " << SL() << "[" << vCS() << "]\n" " _break_match = false\n" " \n" " begin\n" " if _klen > 0\n" " _lower = _keys\n" " _upper = _keys + _klen - 1\n" "\n" " loop do\n" " break if _upper < _lower\n" " _mid = _lower + ( (_upper - _lower) >> 1 )\n" "\n" " if " << GET_WIDE_KEY() << " < " << K() << "[_mid]\n" " _upper = _mid - 1\n" " elsif " << GET_WIDE_KEY() << " > " << K() << "[_mid]\n" " _lower = _mid + 1\n" " else\n" " _trans += (_mid - _keys)\n" " _break_match = true\n" " break\n" " end\n" " end # loop\n" " break if _break_match\n" " _keys += _klen\n" " _trans += _klen\n" " end" "\n" " _klen = " << RL() << "[" << vCS() << "]\n" " if _klen > 0\n" " _lower = _keys\n" " _upper = _keys + (_klen << 1) - 2\n" " loop do\n" " break if _upper < _lower\n" " _mid = _lower + (((_upper-_lower) >> 1) & ~1)\n" " if " << GET_WIDE_KEY() << " < " << K() << "[_mid]\n" " _upper = _mid - 2\n" " elsif " << GET_WIDE_KEY() << " > " << K() << "[_mid+1]\n" " _lower = _mid + 2\n" " else\n" " _trans += ((_mid - _keys) >> 1)\n" " _break_match = true\n" " break\n" " end\n" " end # loop\n" " break if _break_match\n" " _trans += _klen\n" " end\n" " end while false\n"; } void RubyTabCodeGen::writeExec() { out << "begin\n" " _klen, _trans, _keys"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; if ( redFsm->anyConditions() ) out << ", _widec"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) out << ", _acts, _nacts"; out << " = nil\n"; out << " _goto_level = 0\n" " _resume = 10\n" " _eof_trans = 15\n" " _again = 20\n" " _test_eof = 30\n" " _out = 40\n"; out << " while true\n" " _trigger_goto = false\n" " if _goto_level <= 0\n"; if ( !noEnd ) { out << " if " << P() << " == " << PE() << "\n" " _goto_level = _test_eof\n" " next\n" " end\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } /* The resume label. */ out << " end\n" " if _goto_level <= _resume\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << FSA() << "[" << vCS() << "]\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while _nacts > 0\n" " _nacts -= 1\n" " _acts += 1\n" " case " << A() << "[_acts - 1]\n"; FROM_STATE_ACTION_SWITCH(); out << " end # from state action switch\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( useIndicies ) out << " _trans = " << I() << "[_trans]\n"; if ( redFsm->anyEofTrans() ) { out << " end\n" " if _goto_level <= _eof_trans\n"; } if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << "\n"; out << " " << vCS() << " = " << TT() << "[_trans]\n"; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] != 0\n" " _acts = " << TA() << "[_trans]\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while _nacts > 0\n" " _nacts -= 1\n" " _acts += 1\n" " case " << A() << "[_acts - 1]\n"; ACTION_SWITCH(); out << " end # action switch\n" " end\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } /* The again label. */ out << " end\n" " if _goto_level <= _again\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << TSA() << "[" << vCS() << "]\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while _nacts > 0\n" " _nacts -= 1\n" " _acts += 1\n" " case " << A() << "[_acts - 1]\n"; TO_STATE_ACTION_SWITCH(); out << " end # to state action switch\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } out << " " << P() << " += 1\n"; if ( !noEnd ) { out << " if " << P() << " != " << PE() << "\n" " _goto_level = _resume\n" " next\n" " end\n"; } else { out << " _goto_level = _resume\n" " next\n"; } /* The test_eof label. */ out << " end\n" " if _goto_level <= _test_eof\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << "\n"; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " _goto_level = _eof_trans\n" " next;\n" " end\n"; } if ( redFsm->anyEofActions() ) { out << " __acts = " << EA() << "[" << vCS() << "]\n" " __nacts = " << " " << A() << "[__acts]\n" " __acts += 1\n" " while __nacts > 0\n" " __nacts -= 1\n" " __acts += 1\n" " case " << A() << "[__acts - 1]\n"; EOF_ACTION_SWITCH() << " end # eof action switch\n" " end\n" " if _trigger_goto\n" " next\n" " end\n"; } out << "end\n"; } out << " end\n" " if _goto_level <= _out\n" " break\n" " end\n"; /* The loop for next. */ out << " end\n"; /* Wrapping the execute block. */ out << " end\n"; } std::ostream &RubyTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action */ out << " when " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "when " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyTabCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "when " << act->actionId << " then\n"; ACTION( out, act, 0, true ); } } genLineDirective( out ); return out; } std::ostream &RubyTabCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "when " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } void RubyTabCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void RubyTabCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } int RubyTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; return act; } int RubyTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; return act; } int RubyTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; return act; } std::ostream &RubyTabCodeGen::COND_OFFSETS() { START_ARRAY_LINE(); int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ ARRAY_ITEM( INT(curKeyOffset), ++totalStateNum, st.last() ); /* Move the key offset ahead. */ curKeyOffset += st->stateCondList.length(); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::KEY_OFFSETS() { START_ARRAY_LINE(); int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ ARRAY_ITEM( INT(curKeyOffset), ++totalStateNum, st.last() ); /* Move the key offset ahead. */ curKeyOffset += st->outSingle.length() + st->outRange.length()*2; } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::INDEX_OFFSETS() { START_ARRAY_LINE(); int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ ARRAY_ITEM( INT(curIndOffset), ++totalStateNum, st.last() ); /* Move the index offset ahead. */ curIndOffset += st->outSingle.length() + st->outRange.length(); if ( st->defTrans != 0 ) curIndOffset += 1; } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::COND_LENS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ ARRAY_ITEM( INT(st->stateCondList.length()), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::SINGLE_LENS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ ARRAY_ITEM( INT(st->outSingle.length()), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::RANGE_LENS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit length of range index. */ ARRAY_ITEM( INT(st->outRange.length()), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::TO_STATE_ACTIONS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ ARRAY_ITEM( INT(TO_STATE_ACTION(st)), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::FROM_STATE_ACTIONS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ ARRAY_ITEM( INT(FROM_STATE_ACTION(st)), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::EOF_ACTIONS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ ARRAY_ITEM( INT(EOF_ACTION(st)), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::EOF_TRANS() { START_ARRAY_LINE(); int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } /* Write any eof action. */ ARRAY_ITEM( INT(trans), ++totalStateNum, st.last() ); } END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::COND_KEYS() { START_ARRAY_LINE(); int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Lower key. */ ARRAY_ITEM( KEY( sc->lowKey ), ++totalTrans, false ); ARRAY_ITEM( KEY( sc->highKey ), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::COND_SPACES() { START_ARRAY_LINE(); int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Cond Space id. */ ARRAY_ITEM( KEY( sc->condSpace->condSpaceId ), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::KEYS() { START_ARRAY_LINE(); int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { ARRAY_ITEM( KEY( stel->lowKey ), ++totalTrans, false ); } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ ARRAY_ITEM( KEY( rtel->lowKey ), ++totalTrans, false ); /* Upper key. */ ARRAY_ITEM( KEY( rtel->highKey ), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::INDICIES() { int totalTrans = 0; START_ARRAY_LINE(); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { ARRAY_ITEM( KEY( stel->value->id ), ++totalTrans, false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { ARRAY_ITEM( KEY( rtel->value->id ), ++totalTrans, false ); } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { ARRAY_ITEM( KEY( st->defTrans->id ), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::TRANS_TARGS() { int totalTrans = 0; START_ARRAY_LINE(); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; ARRAY_ITEM( KEY( trans->targ->id ), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::TRANS_ACTIONS() { int totalTrans = 0; START_ARRAY_LINE(); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; ARRAY_ITEM( INT(TRANS_ACTION( trans )), ++totalTrans, false ); } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; ARRAY_ITEM( INT(TRANS_ACTION( trans )), ++totalTrans, false ); } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; ARRAY_ITEM( INT(TRANS_ACTION( trans )), ++totalTrans, false ); } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; ARRAY_ITEM( INT(TRANS_ACTION( trans )), ++totalTrans, false ); } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ ARRAY_ITEM( INT(0), ++totalTrans, true ); END_ARRAY_LINE(); return out; } std::ostream &RubyTabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ START_ARRAY_LINE(); int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ ARRAY_ITEM( INT(trans->targ->id), ++totalStates, ( t >= redFsm->transSet.length()-1 ) ); } END_ARRAY_LINE(); delete[] transPtrs; return out; } std::ostream &RubyTabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ START_ARRAY_LINE(); int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; ARRAY_ITEM( INT(TRANS_ACTION( trans )), ++totalAct, ( t >= redFsm->transSet.length()-1 ) ); } END_ARRAY_LINE(); delete[] transPtrs; return out; } void RubyTabCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } /* Local Variables: mode: c++ indent-tabs-mode: 1 c-file-style: "bsd" End: */ ragel-6.10/ragel/csfgoto.h0000664000175000017500000000312713065111230012357 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CSFGOTO_H #define _CSFGOTO_H #include #include "csgoto.h" /* Forwards. */ struct CodeGenData; /* * class CSharpFGotoCodeGen */ class CSharpFGotoCodeGen : public CSharpGotoCodeGen { public: CSharpFGotoCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpGotoCodeGen(out) {} std::ostream &EXEC_ACTIONS(); std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &FINISH_CASES(); std::ostream &EOF_ACTION_SWITCH(); unsigned int TO_STATE_ACTION( RedStateAp *state ); unsigned int FROM_STATE_ACTION( RedStateAp *state ); unsigned int EOF_ACTION( RedStateAp *state ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/xmlcodegen.cpp0000664000175000017500000011041113065111230013366 00000000000000/* * Copyright 2005-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "xmlcodegen.h" #include "parsedata.h" #include "fsmgraph.h" #include "gendata.h" #include "inputdata.h" #include #include "rlparse.h" #include "version.h" using namespace std; GenBase::GenBase( char *fsmName, ParseData *pd, FsmAp *fsm ) : fsmName(fsmName), pd(pd), fsm(fsm), nextActionTableId(0) { } void GenBase::appendTrans( TransListVect &outList, Key lowKey, Key highKey, TransAp *trans ) { if ( trans->toState != 0 || trans->actionTable.length() > 0 ) outList.append( TransEl( lowKey, highKey, trans ) ); } void GenBase::reduceActionTables() { /* Reduce the actions tables to a set. */ for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) { RedActionTable *actionTable = 0; /* Reduce To State Actions. */ if ( st->toStateActionTable.length() > 0 ) { if ( actionTableMap.insert( st->toStateActionTable, &actionTable ) ) actionTable->id = nextActionTableId++; } /* Reduce From State Actions. */ if ( st->fromStateActionTable.length() > 0 ) { if ( actionTableMap.insert( st->fromStateActionTable, &actionTable ) ) actionTable->id = nextActionTableId++; } /* Reduce EOF actions. */ if ( st->eofActionTable.length() > 0 ) { if ( actionTableMap.insert( st->eofActionTable, &actionTable ) ) actionTable->id = nextActionTableId++; } /* Loop the transitions and reduce their actions. */ for ( TransList::Iter trans = st->outList; trans.lte(); trans++ ) { if ( trans->actionTable.length() > 0 ) { if ( actionTableMap.insert( trans->actionTable, &actionTable ) ) actionTable->id = nextActionTableId++; } } } } XMLCodeGen::XMLCodeGen( char *fsmName, ParseData *pd, FsmAp *fsm, std::ostream &out ) : GenBase(fsmName, pd, fsm), out(out) { } void XMLCodeGen::writeActionList() { /* Determine which actions to write. */ int nextActionId = 0; for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) { if ( act->numRefs() > 0 || act->numCondRefs > 0 ) act->actionId = nextActionId++; } /* Write the list. */ out << " \n"; for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) { if ( act->actionId >= 0 ) writeAction( act ); } out << " \n"; } void XMLCodeGen::writeActionTableList() { /* Must first order the action tables based on their id. */ int numTables = nextActionTableId; RedActionTable **tables = new RedActionTable*[numTables]; for ( ActionTableMap::Iter at = actionTableMap; at.lte(); at++ ) tables[at->id] = at; out << " \n"; for ( int t = 0; t < numTables; t++ ) { out << " key.length() << "\">"; for ( ActionTable::Iter atel = tables[t]->key; atel.lte(); atel++ ) { out << atel->value->actionId; if ( ! atel.last() ) out << " "; } out << "\n"; } out << " \n"; delete[] tables; } void XMLCodeGen::writeKey( Key key ) { if ( keyOps->isSigned ) out << key.getVal(); else out << (unsigned long) key.getVal(); } void XMLCodeGen::writeTrans( Key lowKey, Key highKey, TransAp *trans ) { /* First reduce the action. */ RedActionTable *actionTable = 0; if ( trans->actionTable.length() > 0 ) actionTable = actionTableMap.find( trans->actionTable ); /* Write the transition. */ out << " "; writeKey( lowKey ); out << " "; writeKey( highKey ); if ( trans->toState != 0 ) out << " " << trans->toState->alg.stateNum; else out << " x"; if ( actionTable != 0 ) out << " " << actionTable->id; else out << " x"; out << "\n"; } void XMLCodeGen::writeTransList( StateAp *state ) { TransListVect outList; /* If there is only are no ranges the task is simple. */ if ( state->outList.length() > 0 ) { /* Loop each source range. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { /* Reduce the transition. If it reduced to anything then add it. */ appendTrans( outList, trans->lowKey, trans->highKey, trans ); } } out << " \n"; for ( TransListVect::Iter tvi = outList; tvi.lte(); tvi++ ) writeTrans( tvi->lowKey, tvi->highKey, tvi->value ); out << " \n"; } void XMLCodeGen::writeEofTrans( StateAp *state ) { RedActionTable *eofActions = 0; if ( state->eofActionTable.length() > 0 ) eofActions = actionTableMap.find( state->eofActionTable ); /* The is used when there is an eof target, otherwise the eof * action goes into state actions. */ if ( state->eofTarget != 0 ) { out << " " << state->eofTarget->alg.stateNum; if ( eofActions != 0 ) out << " " << eofActions->id; else out << " x"; out << "" << endl; } } void XMLCodeGen::writeText( InlineItem *item ) { if ( item->prev == 0 || item->prev->type != InlineItem::Text ) out << ""; xmlEscapeHost( out, item->data, strlen(item->data) ); if ( item->next == 0 || item->next->type != InlineItem::Text ) out << ""; } void XMLCodeGen::writeGoto( InlineItem *item ) { if ( pd->generatingSectionSubset ) out << "-1"; else { EntryMapEl *targ = fsm->entryPoints.find( item->nameTarg->id ); out << "" << targ->value->alg.stateNum << ""; } } void XMLCodeGen::writeCall( InlineItem *item ) { if ( pd->generatingSectionSubset ) out << "-1"; else { EntryMapEl *targ = fsm->entryPoints.find( item->nameTarg->id ); out << "" << targ->value->alg.stateNum << ""; } } void XMLCodeGen::writeNext( InlineItem *item ) { if ( pd->generatingSectionSubset ) out << "-1"; else { EntryMapEl *targ = fsm->entryPoints.find( item->nameTarg->id ); out << "" << targ->value->alg.stateNum << ""; } } void XMLCodeGen::writeGotoExpr( InlineItem *item ) { out << ""; writeInlineList( item->children ); out << ""; } void XMLCodeGen::writeCallExpr( InlineItem *item ) { out << ""; writeInlineList( item->children ); out << ""; } void XMLCodeGen::writeNextExpr( InlineItem *item ) { out << ""; writeInlineList( item->children ); out << ""; } void XMLCodeGen::writeEntry( InlineItem *item ) { if ( pd->generatingSectionSubset ) out << "-1"; else { EntryMapEl *targ = fsm->entryPoints.find( item->nameTarg->id ); out << "" << targ->value->alg.stateNum << ""; } } void XMLCodeGen::writeActionExec( InlineItem *item ) { out << ""; writeInlineList( item->children ); out << ""; } void XMLCodeGen::writeLmOnLast( InlineItem *item ) { out << "1"; if ( item->longestMatchPart->action != 0 ) { out << ""; writeInlineList( item->longestMatchPart->action->inlineList ); out << ""; } } void XMLCodeGen::writeLmOnNext( InlineItem *item ) { out << "0"; out << ""; if ( item->longestMatchPart->action != 0 ) { out << ""; writeInlineList( item->longestMatchPart->action->inlineList ); out << ""; } } void XMLCodeGen::writeLmOnLagBehind( InlineItem *item ) { out << ""; if ( item->longestMatchPart->action != 0 ) { out << ""; writeInlineList( item->longestMatchPart->action->inlineList ); out << ""; } } void XMLCodeGen::writeLmSwitch( InlineItem *item ) { LongestMatch *longestMatch = item->longestMatch; out << "\n"; /* We can't put the here because we may need to handle the error * case and in that case p should not be changed. Instead use a default * label in the switch to adjust p when user actions are not set. An id of * -1 indicates the default. */ if ( longestMatch->lmSwitchHandlesError ) { /* If the switch handles error then we should have also forced the * error state. */ assert( fsm->errState != 0 ); out << " "; out << "" << fsm->errState->alg.stateNum << ""; out << "\n"; } bool needDefault = false; for ( LmPartList::Iter lmi = *longestMatch->longestMatchList; lmi.lte(); lmi++ ) { if ( lmi->inLmSelect ) { if ( lmi->action == 0 ) needDefault = true; else { /* Open the action. Write it with the context that sets up _p * when doing control flow changes from inside the machine. */ out << " longestMatchId << "\">"; out << ""; writeInlineList( lmi->action->inlineList ); out << "\n"; } } } if ( needDefault ) { out << " " "\n"; } out << " "; } void XMLCodeGen::writeInlineList( InlineList *inlineList ) { for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case InlineItem::Text: writeText( item ); break; case InlineItem::Goto: writeGoto( item ); break; case InlineItem::GotoExpr: writeGotoExpr( item ); break; case InlineItem::Call: writeCall( item ); break; case InlineItem::CallExpr: writeCallExpr( item ); break; case InlineItem::Next: writeNext( item ); break; case InlineItem::NextExpr: writeNextExpr( item ); break; case InlineItem::Break: out << ""; break; case InlineItem::Ret: out << ""; break; case InlineItem::PChar: out << ""; break; case InlineItem::Char: out << ""; break; case InlineItem::Curs: out << ""; break; case InlineItem::Targs: out << ""; break; case InlineItem::Entry: writeEntry( item ); break; case InlineItem::Hold: out << ""; break; case InlineItem::Exec: writeActionExec( item ); break; case InlineItem::LmSetActId: out << "" << item->longestMatchPart->longestMatchId << ""; break; case InlineItem::LmSetTokEnd: out << "1"; break; case InlineItem::LmOnLast: writeLmOnLast( item ); break; case InlineItem::LmOnNext: writeLmOnNext( item ); break; case InlineItem::LmOnLagBehind: writeLmOnLagBehind( item ); break; case InlineItem::LmSwitch: writeLmSwitch( item ); break; case InlineItem::LmInitAct: out << ""; break; case InlineItem::LmInitTokStart: out << ""; break; case InlineItem::LmSetTokStart: out << ""; break; } } } BackendGen::BackendGen( char *fsmName, ParseData *pd, FsmAp *fsm, CodeGenData *cgd ) : GenBase(fsmName, pd, fsm), cgd(cgd) { } void BackendGen::makeText( GenInlineList *outList, InlineItem *item ) { GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::Text ); inlineItem->data = item->data; outList->append( inlineItem ); } void BackendGen::makeTargetItem( GenInlineList *outList, NameInst *nameTarg, GenInlineItem::Type type ) { long targetState; if ( pd->generatingSectionSubset ) targetState = -1; else { EntryMapEl *targ = fsm->entryPoints.find( nameTarg->id ); targetState = targ->value->alg.stateNum; } /* Make the item. */ GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), type ); inlineItem->targId = targetState; outList->append( inlineItem ); } /* Make a sublist item with a given type. */ void BackendGen::makeSubList( GenInlineList *outList, InlineList *inlineList, GenInlineItem::Type type ) { /* Fill the sub list. */ GenInlineList *subList = new GenInlineList; makeGenInlineList( subList, inlineList ); /* Make the item. */ GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), type ); inlineItem->children = subList; outList->append( inlineItem ); } void BackendGen::makeLmOnLast( GenInlineList *outList, InlineItem *item ) { makeSetTokend( outList, 1 ); if ( item->longestMatchPart->action != 0 ) { makeSubList( outList, item->longestMatchPart->action->inlineList, GenInlineItem::SubAction ); } } void BackendGen::makeLmOnNext( GenInlineList *outList, InlineItem *item ) { makeSetTokend( outList, 0 ); outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Hold ) ); if ( item->longestMatchPart->action != 0 ) { makeSubList( outList, item->longestMatchPart->action->inlineList, GenInlineItem::SubAction ); } } void BackendGen::makeExecGetTokend( GenInlineList *outList ) { /* Make the Exec item. */ GenInlineItem *execItem = new GenInlineItem( InputLoc(), GenInlineItem::Exec ); execItem->children = new GenInlineList; /* Make the GetTokEnd */ GenInlineItem *getTokend = new GenInlineItem( InputLoc(), GenInlineItem::LmGetTokEnd ); execItem->children->append( getTokend ); outList->append( execItem ); } void BackendGen::makeLmOnLagBehind( GenInlineList *outList, InlineItem *item ) { /* Jump to the tokend. */ makeExecGetTokend( outList ); if ( item->longestMatchPart->action != 0 ) { makeSubList( outList, item->longestMatchPart->action->inlineList, GenInlineItem::SubAction ); } } void BackendGen::makeLmSwitch( GenInlineList *outList, InlineItem *item ) { GenInlineItem *lmSwitch = new GenInlineItem( InputLoc(), GenInlineItem::LmSwitch ); GenInlineList *lmList = lmSwitch->children = new GenInlineList; LongestMatch *longestMatch = item->longestMatch; /* We can't put the here because we may need to handle the error * case and in that case p should not be changed. Instead use a default * label in the switch to adjust p when user actions are not set. An id of * -1 indicates the default. */ if ( longestMatch->lmSwitchHandlesError ) { /* If the switch handles error then we should have also forced the * error state. */ assert( fsm->errState != 0 ); GenInlineItem *errCase = new GenInlineItem( InputLoc(), GenInlineItem::SubAction ); errCase->lmId = 0; errCase->children = new GenInlineList; /* Make the item. */ GenInlineItem *gotoItem = new GenInlineItem( InputLoc(), GenInlineItem::Goto ); gotoItem->targId = fsm->errState->alg.stateNum; errCase->children->append( gotoItem ); lmList->append( errCase ); } bool needDefault = false; for ( LmPartList::Iter lmi = *longestMatch->longestMatchList; lmi.lte(); lmi++ ) { if ( lmi->inLmSelect ) { if ( lmi->action == 0 ) needDefault = true; else { /* Open the action. Write it with the context that sets up _p * when doing control flow changes from inside the machine. */ GenInlineItem *lmCase = new GenInlineItem( InputLoc(), GenInlineItem::SubAction ); lmCase->lmId = lmi->longestMatchId; lmCase->children = new GenInlineList; makeExecGetTokend( lmCase->children ); makeGenInlineList( lmCase->children, lmi->action->inlineList ); lmList->append( lmCase ); } } } if ( needDefault ) { GenInlineItem *defCase = new GenInlineItem( InputLoc(), GenInlineItem::SubAction ); defCase->lmId = -1; defCase->children = new GenInlineList; makeExecGetTokend( defCase->children ); lmList->append( defCase ); } outList->append( lmSwitch ); } void BackendGen::makeSetTokend( GenInlineList *outList, long offset ) { GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetTokEnd ); inlineItem->offset = offset; outList->append( inlineItem ); } void BackendGen::makeSetAct( GenInlineList *outList, long lmId ) { GenInlineItem *inlineItem = new GenInlineItem( InputLoc(), GenInlineItem::LmSetActId ); inlineItem->lmId = lmId; outList->append( inlineItem ); } void BackendGen::makeGenInlineList( GenInlineList *outList, InlineList *inList ) { for ( InlineList::Iter item = *inList; item.lte(); item++ ) { switch ( item->type ) { case InlineItem::Text: makeText( outList, item ); break; case InlineItem::Goto: makeTargetItem( outList, item->nameTarg, GenInlineItem::Goto ); break; case InlineItem::GotoExpr: makeSubList( outList, item->children, GenInlineItem::GotoExpr ); break; case InlineItem::Call: makeTargetItem( outList, item->nameTarg, GenInlineItem::Call ); break; case InlineItem::CallExpr: makeSubList( outList, item->children, GenInlineItem::CallExpr ); break; case InlineItem::Next: makeTargetItem( outList, item->nameTarg, GenInlineItem::Next ); break; case InlineItem::NextExpr: makeSubList( outList, item->children, GenInlineItem::NextExpr ); break; case InlineItem::Break: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Break ) ); break; case InlineItem::Ret: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Ret ) ); break; case InlineItem::PChar: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::PChar ) ); break; case InlineItem::Char: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Char ) ); break; case InlineItem::Curs: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Curs ) ); break; case InlineItem::Targs: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Targs ) ); break; case InlineItem::Entry: makeTargetItem( outList, item->nameTarg, GenInlineItem::Entry ); break; case InlineItem::Hold: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::Hold ) ); break; case InlineItem::Exec: makeSubList( outList, item->children, GenInlineItem::Exec ); break; case InlineItem::LmSetActId: makeSetAct( outList, item->longestMatchPart->longestMatchId ); break; case InlineItem::LmSetTokEnd: makeSetTokend( outList, 1 ); break; case InlineItem::LmOnLast: makeLmOnLast( outList, item ); break; case InlineItem::LmOnNext: makeLmOnNext( outList, item ); break; case InlineItem::LmOnLagBehind: makeLmOnLagBehind( outList, item ); break; case InlineItem::LmSwitch: makeLmSwitch( outList, item ); break; case InlineItem::LmInitAct: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::LmInitAct ) ); break; case InlineItem::LmInitTokStart: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::LmInitTokStart ) ); break; case InlineItem::LmSetTokStart: outList->append( new GenInlineItem( InputLoc(), GenInlineItem::LmSetTokStart ) ); cgd->hasLongestMatch = true; break; } } } void XMLCodeGen::writeAction( Action *action ) { out << " actionId << "\""; if ( action->name != 0 ) out << " name=\"" << action->name << "\""; out << " line=\"" << action->loc.line << "\" col=\"" << action->loc.col << "\">"; writeInlineList( action->inlineList ); out << "\n"; } void xmlEscapeHost( std::ostream &out, char *data, long len ) { char *end = data + len; while ( data != end ) { switch ( *data ) { case '<': out << "<"; break; case '>': out << ">"; break; case '&': out << "&"; break; default: out << *data; break; } data += 1; } } void XMLCodeGen::writeStateActions( StateAp *state ) { RedActionTable *toStateActions = 0; if ( state->toStateActionTable.length() > 0 ) toStateActions = actionTableMap.find( state->toStateActionTable ); RedActionTable *fromStateActions = 0; if ( state->fromStateActionTable.length() > 0 ) fromStateActions = actionTableMap.find( state->fromStateActionTable ); /* EOF actions go out here only if the state has no eof target. If it has * an eof target then an eof transition will be used instead. */ RedActionTable *eofActions = 0; if ( state->eofTarget == 0 && state->eofActionTable.length() > 0 ) eofActions = actionTableMap.find( state->eofActionTable ); if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) { out << " "; if ( toStateActions != 0 ) out << toStateActions->id; else out << "x"; if ( fromStateActions != 0 ) out << " " << fromStateActions->id; else out << " x"; if ( eofActions != 0 ) out << " " << eofActions->id; else out << " x"; out << "\n"; } } void XMLCodeGen::writeStateConditions( StateAp *state ) { if ( state->stateCondList.length() > 0 ) { out << " stateCondList.length() << "\">\n"; for ( StateCondList::Iter scdi = state->stateCondList; scdi.lte(); scdi++ ) { out << " "; writeKey( scdi->lowKey ); out << " "; writeKey( scdi->highKey ); out << " "; out << scdi->condSpace->condSpaceId; out << "\n"; } out << " \n"; } } void XMLCodeGen::writeStateList() { /* Write the list of states. */ out << " stateList.length() << "\">\n"; for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) { out << " alg.stateNum << "\""; if ( st->isFinState() ) out << " final=\"t\""; out << ">\n"; writeStateActions( st ); writeEofTrans( st ); writeStateConditions( st ); writeTransList( st ); out << " \n"; if ( !st.last() ) out << "\n"; } out << " \n"; } bool XMLCodeGen::writeNameInst( NameInst *nameInst ) { bool written = false; if ( nameInst->parent != 0 ) written = writeNameInst( nameInst->parent ); if ( nameInst->name != 0 ) { if ( written ) out << '_'; out << nameInst->name; written = true; } return written; } void XMLCodeGen::writeEntryPoints() { /* List of entry points other than start state. */ if ( fsm->entryPoints.length() > 0 || pd->lmRequiresErrorState ) { out << " lmRequiresErrorState ) out << " error=\"t\""; out << ">\n"; for ( EntryMap::Iter en = fsm->entryPoints; en.lte(); en++ ) { /* Get the name instantiation from nameIndex. */ NameInst *nameInst = pd->nameIndex[en->key]; StateAp *state = en->value; out << " " << state->alg.stateNum << "\n"; } out << " \n"; } } void XMLCodeGen::writeMachine() { /* Open the machine. */ out << " \n"; /* Action tables. */ reduceActionTables(); writeActionList(); writeActionTableList(); writeConditions(); /* Start state. */ out << " " << fsm->startState->alg.stateNum << "\n"; /* Error state. */ if ( fsm->errState != 0 ) { out << " " << fsm->errState->alg.stateNum << "\n"; } writeEntryPoints(); writeStateList(); out << " \n"; } void XMLCodeGen::writeConditions() { if ( condData->condSpaceMap.length() > 0 ) { long nextCondSpaceId = 0; for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) cs->condSpaceId = nextCondSpaceId++; out << " condSpaceMap.length() << "\">\n"; for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) { out << " condSpaceId << "\" length=\"" << cs->condSet.length() << "\">"; writeKey( cs->baseKey ); for ( CondSet::Iter csi = cs->condSet; csi.lte(); csi++ ) out << " " << (*csi)->actionId; out << "\n"; } out << " \n"; } } void XMLCodeGen::writeExports() { if ( pd->exportList.length() > 0 ) { out << " \n"; for ( ExportList::Iter exp = pd->exportList; exp.lte(); exp++ ) { out << " name << "\">"; writeKey( exp->key ); out << "\n"; } out << " \n"; } } void XMLCodeGen::writeXML() { /* Open the definition. */ out << "\n"; /* Alphabet type. */ out << " " << keyOps->alphType->internalName << "\n"; /* Getkey expression. */ if ( pd->getKeyExpr != 0 ) { out << " "; writeInlineList( pd->getKeyExpr ); out << "\n"; } /* Access expression. */ if ( pd->accessExpr != 0 ) { out << " "; writeInlineList( pd->accessExpr ); out << "\n"; } /* PrePush expression. */ if ( pd->prePushExpr != 0 ) { out << " "; writeInlineList( pd->prePushExpr ); out << "\n"; } /* PostPop expression. */ if ( pd->postPopExpr != 0 ) { out << " "; writeInlineList( pd->postPopExpr ); out << "\n"; } /* * Variable expressions. */ if ( pd->pExpr != 0 ) { out << " "; writeInlineList( pd->pExpr ); out << "\n"; } if ( pd->peExpr != 0 ) { out << " "; writeInlineList( pd->peExpr ); out << "\n"; } if ( pd->eofExpr != 0 ) { out << " "; writeInlineList( pd->eofExpr ); out << "\n"; } if ( pd->csExpr != 0 ) { out << " "; writeInlineList( pd->csExpr ); out << "\n"; } if ( pd->topExpr != 0 ) { out << " "; writeInlineList( pd->topExpr ); out << "\n"; } if ( pd->stackExpr != 0 ) { out << " "; writeInlineList( pd->stackExpr ); out << "\n"; } if ( pd->actExpr != 0 ) { out << " "; writeInlineList( pd->actExpr ); out << "\n"; } if ( pd->tokstartExpr != 0 ) { out << " "; writeInlineList( pd->tokstartExpr ); out << "\n"; } if ( pd->tokendExpr != 0 ) { out << " "; writeInlineList( pd->tokendExpr ); out << "\n"; } if ( pd->dataExpr != 0 ) { out << " "; writeInlineList( pd->dataExpr ); out << "\n"; } writeExports(); writeMachine(); out << "\n"; } void BackendGen::makeExports() { for ( ExportList::Iter exp = pd->exportList; exp.lte(); exp++ ) cgd->exportList.append( new Export( exp->name, exp->key ) ); } void BackendGen::makeAction( Action *action ) { GenInlineList *genList = new GenInlineList; makeGenInlineList( genList, action->inlineList ); cgd->newAction( curAction++, action->name, action->loc, genList ); } void BackendGen::makeActionList() { /* Determine which actions to write. */ int nextActionId = 0; for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) { if ( act->numRefs() > 0 || act->numCondRefs > 0 ) act->actionId = nextActionId++; } /* Write the list. */ cgd->initActionList( nextActionId ); curAction = 0; for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) { if ( act->actionId >= 0 ) makeAction( act ); } } void BackendGen::makeActionTableList() { /* Must first order the action tables based on their id. */ int numTables = nextActionTableId; RedActionTable **tables = new RedActionTable*[numTables]; for ( ActionTableMap::Iter at = actionTableMap; at.lte(); at++ ) tables[at->id] = at; cgd->initActionTableList( numTables ); curActionTable = 0; for ( int t = 0; t < numTables; t++ ) { long length = tables[t]->key.length(); /* Collect the action table. */ RedAction *redAct = cgd->allActionTables + curActionTable; redAct->actListId = curActionTable; redAct->key.setAsNew( length ); for ( ActionTable::Iter atel = tables[t]->key; atel.lte(); atel++ ) { redAct->key[atel.pos()].key = 0; redAct->key[atel.pos()].value = cgd->allActions + atel->value->actionId; } /* Insert into the action table map. */ cgd->redFsm->actionMap.insert( redAct ); curActionTable += 1; } delete[] tables; } void BackendGen::makeConditions() { if ( condData->condSpaceMap.length() > 0 ) { long nextCondSpaceId = 0; for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) cs->condSpaceId = nextCondSpaceId++; long listLength = condData->condSpaceMap.length(); cgd->initCondSpaceList( listLength ); curCondSpace = 0; for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) { long id = cs->condSpaceId; cgd->newCondSpace( curCondSpace, id, cs->baseKey ); for ( CondSet::Iter csi = cs->condSet; csi.lte(); csi++ ) cgd->condSpaceItem( curCondSpace, (*csi)->actionId ); curCondSpace += 1; } } } bool BackendGen::makeNameInst( std::string &res, NameInst *nameInst ) { bool written = false; if ( nameInst->parent != 0 ) written = makeNameInst( res, nameInst->parent ); if ( nameInst->name != 0 ) { if ( written ) res += '_'; res += nameInst->name; written = true; } return written; } void BackendGen::makeEntryPoints() { /* List of entry points other than start state. */ if ( fsm->entryPoints.length() > 0 || pd->lmRequiresErrorState ) { if ( pd->lmRequiresErrorState ) cgd->setForcedErrorState(); for ( EntryMap::Iter en = fsm->entryPoints; en.lte(); en++ ) { /* Get the name instantiation from nameIndex. */ NameInst *nameInst = pd->nameIndex[en->key]; std::string name; makeNameInst( name, nameInst ); StateAp *state = en->value; cgd->addEntryPoint( strdup(name.c_str()), state->alg.stateNum ); } } } void BackendGen::makeStateActions( StateAp *state ) { RedActionTable *toStateActions = 0; if ( state->toStateActionTable.length() > 0 ) toStateActions = actionTableMap.find( state->toStateActionTable ); RedActionTable *fromStateActions = 0; if ( state->fromStateActionTable.length() > 0 ) fromStateActions = actionTableMap.find( state->fromStateActionTable ); /* EOF actions go out here only if the state has no eof target. If it has * an eof target then an eof transition will be used instead. */ RedActionTable *eofActions = 0; if ( state->eofTarget == 0 && state->eofActionTable.length() > 0 ) eofActions = actionTableMap.find( state->eofActionTable ); if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) { long to = -1; if ( toStateActions != 0 ) to = toStateActions->id; long from = -1; if ( fromStateActions != 0 ) from = fromStateActions->id; long eof = -1; if ( eofActions != 0 ) eof = eofActions->id; cgd->setStateActions( curState, to, from, eof ); } } void BackendGen::makeEofTrans( StateAp *state ) { RedActionTable *eofActions = 0; if ( state->eofActionTable.length() > 0 ) eofActions = actionTableMap.find( state->eofActionTable ); /* The EOF trans is used when there is an eof target, otherwise the eof * action goes into state actions. */ if ( state->eofTarget != 0 ) { long targ = state->eofTarget->alg.stateNum; long action = -1; if ( eofActions != 0 ) action = eofActions->id; cgd->setEofTrans( curState, targ, action ); } } void BackendGen::makeStateConditions( StateAp *state ) { if ( state->stateCondList.length() > 0 ) { long length = state->stateCondList.length(); cgd->initStateCondList( curState, length ); curStateCond = 0; for ( StateCondList::Iter scdi = state->stateCondList; scdi.lte(); scdi++ ) { cgd->addStateCond( curState, scdi->lowKey, scdi->highKey, scdi->condSpace->condSpaceId ); } } } void BackendGen::makeTrans( Key lowKey, Key highKey, TransAp *trans ) { /* First reduce the action. */ RedActionTable *actionTable = 0; if ( trans->actionTable.length() > 0 ) actionTable = actionTableMap.find( trans->actionTable ); long targ = -1; if ( trans->toState != 0 ) targ = trans->toState->alg.stateNum; long action = -1; if ( actionTable != 0 ) action = actionTable->id; cgd->newTrans( curState, curTrans++, lowKey, highKey, targ, action ); } void BackendGen::makeTransList( StateAp *state ) { TransListVect outList; /* If there is only are no ranges the task is simple. */ if ( state->outList.length() > 0 ) { /* Loop each source range. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { /* Reduce the transition. If it reduced to anything then add it. */ appendTrans( outList, trans->lowKey, trans->highKey, trans ); } } cgd->initTransList( curState, outList.length() ); curTrans = 0; for ( TransListVect::Iter tvi = outList; tvi.lte(); tvi++ ) makeTrans( tvi->lowKey, tvi->highKey, tvi->value ); cgd->finishTransList( curState ); } void BackendGen::makeStateList() { /* Write the list of states. */ long length = fsm->stateList.length(); cgd->initStateList( length ); curState = 0; for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) { makeStateActions( st ); makeEofTrans( st ); makeStateConditions( st ); makeTransList( st ); long id = st->alg.stateNum; cgd->setId( curState, id ); if ( st->isFinState() ) cgd->setFinal( curState ); curState += 1; } } void BackendGen::makeMachine() { cgd->createMachine(); /* Action tables. */ reduceActionTables(); makeActionList(); makeActionTableList(); makeConditions(); /* Start State. */ cgd->setStartState( fsm->startState->alg.stateNum ); /* Error state. */ if ( fsm->errState != 0 ) cgd->setErrorState( fsm->errState->alg.stateNum ); makeEntryPoints(); makeStateList(); cgd->closeMachine(); } void BackendGen::close_ragel_def() { /* Do this before distributing transitions out to singles and defaults * makes life easier. */ cgd->redFsm->maxKey = cgd->findMaxKey(); cgd->redFsm->assignActionLocs(); /* Find the first final state (The final state with the lowest id). */ cgd->redFsm->findFirstFinState(); /* Call the user's callback. */ cgd->finishRagelDef(); } void BackendGen::makeBackend() { /* Alphabet type. */ cgd->setAlphType( keyOps->alphType->internalName ); /* Getkey expression. */ if ( pd->getKeyExpr != 0 ) { cgd->getKeyExpr = new GenInlineList; makeGenInlineList( cgd->getKeyExpr, pd->getKeyExpr ); } /* Access expression. */ if ( pd->accessExpr != 0 ) { cgd->accessExpr = new GenInlineList; makeGenInlineList( cgd->accessExpr, pd->accessExpr ); } /* PrePush expression. */ if ( pd->prePushExpr != 0 ) { cgd->prePushExpr = new GenInlineList; makeGenInlineList( cgd->prePushExpr, pd->prePushExpr ); } /* PostPop expression. */ if ( pd->postPopExpr != 0 ) { cgd->postPopExpr = new GenInlineList; makeGenInlineList( cgd->postPopExpr, pd->postPopExpr ); } /* * Variable expressions. */ if ( pd->pExpr != 0 ) { cgd->pExpr = new GenInlineList; makeGenInlineList( cgd->pExpr, pd->pExpr ); } if ( pd->peExpr != 0 ) { cgd->peExpr = new GenInlineList; makeGenInlineList( cgd->peExpr, pd->peExpr ); } if ( pd->eofExpr != 0 ) { cgd->eofExpr = new GenInlineList; makeGenInlineList( cgd->eofExpr, pd->eofExpr ); } if ( pd->csExpr != 0 ) { cgd->csExpr = new GenInlineList; makeGenInlineList( cgd->csExpr, pd->csExpr ); } if ( pd->topExpr != 0 ) { cgd->topExpr = new GenInlineList; makeGenInlineList( cgd->topExpr, pd->topExpr ); } if ( pd->stackExpr != 0 ) { cgd->stackExpr = new GenInlineList; makeGenInlineList( cgd->stackExpr, pd->stackExpr ); } if ( pd->actExpr != 0 ) { cgd->actExpr = new GenInlineList; makeGenInlineList( cgd->actExpr, pd->actExpr ); } if ( pd->tokstartExpr != 0 ) { cgd->tokstartExpr = new GenInlineList; makeGenInlineList( cgd->tokstartExpr, pd->tokstartExpr ); } if ( pd->tokendExpr != 0 ) { cgd->tokendExpr = new GenInlineList; makeGenInlineList( cgd->tokendExpr, pd->tokendExpr ); } if ( pd->dataExpr != 0 ) { cgd->dataExpr = new GenInlineList; makeGenInlineList( cgd->dataExpr, pd->dataExpr ); } makeExports(); makeMachine(); close_ragel_def(); } void InputData::writeLanguage( std::ostream &out ) { out << " lang=\""; switch ( hostLang->lang ) { case HostLang::C: out << "C"; break; case HostLang::D: out << "D"; break; case HostLang::D2: out << "D2"; break; case HostLang::Go: out << "Go"; break; case HostLang::Java: out << "Java"; break; case HostLang::Ruby: out << "Ruby"; break; case HostLang::CSharp: out << "C#"; break; case HostLang::OCaml: out << "OCaml"; break; } out << "\""; } void InputData::writeXML( std::ostream &out ) { out << "\n"; for ( ParserDict::Iter parser = parserDict; parser.lte(); parser++ ) { ParseData *pd = parser->value->pd; if ( pd->instanceList.length() > 0 ) pd->generateXML( *outStream ); } out << "\n"; } ragel-6.10/ragel/cdgoto.h0000664000175000017500000000674513065111230012203 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDGOTO_H #define _CDGOTO_H #include #include "cdcodegen.h" /* Forwards. */ struct CodeGenData; struct NameInst; struct RedTransAp; struct RedStateAp; struct GenStateCond; /* * Goto driven fsm. */ class GotoCodeGen : virtual public FsmCodeGen { public: GotoCodeGen( ostream &out ) : FsmCodeGen(out) {} std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &STATE_GOTOS(); std::ostream &TRANSITIONS(); std::ostream &EXEC_FUNCS(); std::ostream &FINISH_CASES(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void RET( ostream &ret, bool inFinish ); void BREAK( ostream &ret, int targState, bool csForced ); virtual unsigned int TO_STATE_ACTION( RedStateAp *state ); virtual unsigned int FROM_STATE_ACTION( RedStateAp *state ); virtual unsigned int EOF_ACTION( RedStateAp *state ); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); void COND_TRANSLATE( GenStateCond *stateCond, int level ); void emitCondBSearch( RedStateAp *state, int level, int low, int high ); void STATE_CONDS( RedStateAp *state, bool genDefault ); virtual std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); void emitSingleSwitch( RedStateAp *state ); void emitRangeBSearch( RedStateAp *state, int level, int low, int high ); /* Called from STATE_GOTOS just before writing the gotos */ virtual void GOTO_HEADER( RedStateAp *state ); virtual void STATE_GOTO_ERROR(); virtual void writeData(); virtual void writeExec(); }; /* * class CGotoCodeGen */ struct CGotoCodeGen : public GotoCodeGen, public CCodeGen { CGotoCodeGen( ostream &out ) : FsmCodeGen(out), GotoCodeGen(out), CCodeGen(out) {} }; /* * class DGotoCodeGen */ struct DGotoCodeGen : public GotoCodeGen, public DCodeGen { DGotoCodeGen( ostream &out ) : FsmCodeGen(out), GotoCodeGen(out), DCodeGen(out) {} }; /* * class D2GotoCodeGen */ struct D2GotoCodeGen : public GotoCodeGen, public D2CodeGen { D2GotoCodeGen( ostream &out ) : FsmCodeGen(out), GotoCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/mlflat.cpp0000664000175000017500000005465513065111230012541 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "ragel.h" #include "mlflat.h" #include "redfsm.h" #include "gendata.h" std::ostream &OCamlFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &OCamlFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &OCamlFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &OCamlFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &OCamlFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFlatCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, true ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFlatCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\t| " << act->actionId << " ->\n"; ACTION( out, act, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFlatCodeGen::FLAT_INDEX_OFFSET() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ if ( st->transList != 0 ) curIndOffset += keyOps->span( st->lowKey, st->highKey ); if ( st->defTrans != 0 ) curIndOffset += 1; } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::KEY_SPANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->transList != 0 ) span = keyOps->span( st->lowKey, st->highKey ); out << span; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::TO_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::FROM_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::EOF_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::EOF_TRANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::COND_KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just cond low key and cond high key. */ out << ALPHA_KEY( st->condLowKey ) << ARR_SEP(); out << ALPHA_KEY( st->condHighKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << /*"(char) " <<*/ 0 << "\n"; return out; } std::ostream &OCamlFlatCodeGen::COND_KEY_SPANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->condList != 0 ) span = keyOps->span( st->condLowKey, st->condHighKey ); out << span; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::CONDS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->condList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->condList[pos] != 0 ) out << st->condList[pos]->condSpaceId + 1 << ARR_SEP(); else out << "0" << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlFlatCodeGen::COND_INDEX_OFFSET() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ARR_SEP(); if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ if ( st->condList != 0 ) curIndOffset += keyOps->span( st->condLowKey, st->condHighKey ); } out << "\n"; return out; } std::ostream &OCamlFlatCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just low key and high key. */ out << ALPHA_KEY( st->lowKey ) << ARR_SEP(); out << ALPHA_KEY( st->highKey ) << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << /*"(char) " <<*/ 0 << "\n"; return out; } std::ostream &OCamlFlatCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->transList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->lowKey, st->highKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { out << st->transList[pos]->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* The state's default index goes next. */ if ( st->defTrans != 0 ) out << st->defTrans->id << ARR_SEP(); if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &OCamlFlatCodeGen::TRANS_TARGS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ARR_SEP(); if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } std::ostream &OCamlFlatCodeGen::TRANS_ACTIONS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ARR_SEP(); if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } void OCamlFlatCodeGen::LOCATE_TRANS() { std::ostringstream temp; temp << "inds + (\n" " if slen > 0 && " << AT( K(), "keys" ) << " <= " << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= " << AT( K(), "keys+1" ) << " then\n" " " << GET_WIDE_KEY() << " - " << AT(K(), "keys" ) << " else slen)"; out << " let keys = " << vCS() << " lsl 1 in\n" " let inds = " << AT( IO(), vCS() ) << " in\n" "\n" " let slen = " << AT( SP(), vCS() ) << " in\n" " state.trans <- " << AT( I(), temp.str() ) << ";\n" "\n"; } void OCamlFlatCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "begin " << vCS() << " <- " << gotoDest << "; " << CTRL_FLOW() << "raise Goto_again end"; } void OCamlFlatCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "begin " << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << " raise Goto_again end"; } void OCamlFlatCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void OCamlFlatCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void OCamlFlatCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " <- " << nextDest << ";"; } void OCamlFlatCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void OCamlFlatCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin " << AT( STACK(), POST_INCR(TOP()) ) << " <- " << vCS() << "; "; ret << vCS() << " <- " << callDest << "; " << CTRL_FLOW() << "raise Goto_again end "; if ( prePushExpr != 0 ) ret << "end"; } void OCamlFlatCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin " << AT(STACK(), POST_INCR(TOP()) ) << " <- " << vCS() << "; " << vCS() << " <- ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << "); " << CTRL_FLOW() << "raise Goto_again end "; if ( prePushExpr != 0 ) ret << "end"; } void OCamlFlatCodeGen::RET( ostream &ret, bool inFinish ) { ret << "begin " << vCS() << " <- " << AT(STACK(), PRE_DECR(TOP()) ) << "; "; if ( postPopExpr != 0 ) { ret << "begin "; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "end "; } ret << CTRL_FLOW() << "raise Goto_again end"; } void OCamlFlatCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; ret << "begin " << P() << " <- " << P() << " + 1; " << CTRL_FLOW() << "raise Goto_out end"; } void OCamlFlatCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); out << "type " << TYPE_STATE() << " = { mutable trans : int; mutable acts : int; mutable nacts : int; }" << TOP_SEP(); out << "exception Goto_match" << TOP_SEP(); out << "exception Goto_again" << TOP_SEP(); out << "exception Goto_eof_trans" << TOP_SEP(); } void OCamlFlatCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << ";\n"; out << " _keys = " << vCS() << "<<1;\n" " _conds = " << CO() << "[" << vCS() << "];\n" // " _keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n" // " _conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n" "\n" " _slen = " << CSP() << "[" << vCS() << "];\n" " if (_slen > 0 && " << CK() << "[_keys] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= " << CK() << "[_keys+1])\n" " _cond = " << C() << "[_conds+" << GET_WIDE_KEY() << " - " << CK() << "[_keys]];\n" " else\n" " _cond = 0;" "\n"; /* XXX This version of the code doesn't work because Mono is weird. Works * fine in Microsoft's csc, even though the bug report filed claimed it * didn't. " _slen = " << CSP() << "[" << vCS() << "];\n" " _cond = _slen > 0 && " << CK() << "[_keys] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= " << CK() << "[_keys+1] ?\n" " " << C() << "[_conds+" << GET_WIDE_KEY() << " - " << CK() << "[_keys]] : 0;\n" "\n"; */ out << " switch ( _cond ) {\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId + 1 << ": {\n"; out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } out << " }\n"; out << " break;\n"; } SWITCH_DEFAULT(); out << " }\n"; } void OCamlFlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " begin\n"; // " " << slenType << " _slen"; // if ( redFsm->anyRegCurStateRef() ) // out << ", _ps"; // out << // " " << transType << " _trans"; // if ( redFsm->anyConditions() ) // out << ", _cond"; // out << ";\n"; // if ( redFsm->anyToStateActions() || // redFsm->anyRegActions() || redFsm->anyFromStateActions() ) // { // out << // " int _acts;\n" // " int _nacts;\n"; // } // out << // " " << "int _keys;\n" // " " << indsType << " _inds;\n"; /* " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n" " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/ if ( redFsm->anyConditions() ) { out << " " << condsType << " _conds;\n" " " << WIDE_ALPH_TYPE() << " _widec;\n"; } out << "\n"; out << " let state = { trans = 0; acts = 0; nacts = 0; } in\n" " let rec do_start () =\n"; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " = " << PE() << " then\n" " do_test_eof ()\n" "\telse\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " = " << redFsm->errState->id << " then\n" " do_out ()\n" "\telse\n"; } out << "\tdo_resume ()\n"; out << "and do_resume () =\n"; if ( redFsm->anyFromStateActions() ) { out << " state.acts <- " << AT( FSA(), vCS() ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n" " done;\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); // out << "\tbegin try\n"; LOCATE_TRANS(); // out << "\twith Goto_match -> () end;\n"; out << "\tdo_eof_trans ()\n"; // if ( redFsm->anyEofTrans() ) out << "and do_eof_trans () =\n"; if ( redFsm->anyRegCurStateRef() ) out << " let ps = " << vCS() << " in\n"; out << " " << vCS() << " <- " << AT( TT() ,"state.trans" ) << ";\n" "\n"; if ( redFsm->anyRegActions() ) { out << "\tbegin try\n" " match " << AT( TA(), "state.trans" ) << " with\n" "\t| 0 -> raise Goto_again\n" "\t| _ ->\n" " state.acts <- " << AT( TA(), "state.trans" ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" " done\n" "\twith Goto_again -> () end;\n"; } out << "\tdo_again ()\n"; // if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || // redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "\tand do_again () =\n"; if ( redFsm->anyToStateActions() ) { out << " state.acts <- " << AT( TSA(), vCS() ) << ";\n" " state.nacts <- " << AT( A(), POST_INCR("state.acts") ) << ";\n" " while " << POST_DECR("state.nacts") << " > 0 do\n" " begin match " << AT( A(), POST_INCR("state.acts") ) << " with\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n" " done;\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " match " << vCS() << " with\n" "\t| " << redFsm->errState->id << " -> do_out ()\n" "\t| _ ->\n"; } out << "\t" << P() << " <- " << P() << " + 1;\n"; if ( !noEnd ) { out << " if " << P() << " <> " << PE() << " then\n" " do_resume ()\n" "\telse do_test_eof ()\n"; } else { out << " do_resume ()\n"; } // if ( testEofUsed ) out << "and do_test_eof () =\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " = " << vEOF() << " then\n" " begin try\n"; if ( redFsm->anyEofTrans() ) { out << " if " << AT( ET(), vCS() ) << " > 0 then\n" " begin\n" " state.trans <- " << CAST(transType) << "(" << AT( ET(), vCS() ) << " - 1);\n" " raise Goto_eof_trans;\n" " end;\n"; } if ( redFsm->anyEofActions() ) { out << " let __acts = ref " << AT( EA(), vCS() ) << " in\n" " let __nacts = ref " << AT( A(), "!__acts" ) << " in\n" " incr __acts;\n" " while !__nacts > 0 do\n" " decr __nacts;\n" " begin match " << AT( A(), POST_INCR("__acts.contents") ) << " with\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" " done\n"; } out << " with Goto_again -> do_again ()\n" " | Goto_eof_trans -> do_eof_trans () end\n" "\n"; } else { out << "\t()\n"; } if ( outLabelUsed ) out << " and do_out () = ()\n"; out << "\tin do_start ()\n"; out << " end;\n"; } void OCamlFlatCodeGen::initVarTypes() { slenType = ARRAY_TYPE(MAX(redFsm->maxSpan, redFsm->maxCondSpan)); transType = ARRAY_TYPE(redFsm->maxIndex+1); indsType = ARRAY_TYPE(redFsm->maxFlatIndexOffset); condsType = ARRAY_TYPE(redFsm->maxCondIndexOffset); } ragel-6.10/ragel/fsmap.cpp0000664000175000017500000007157313065111230012366 00000000000000/* * Copyright 2002-2004 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "fsmgraph.h" #include using std::cerr; using std::endl; CondData *condData = 0; KeyOps *keyOps = 0; /* Insert an action into an action table. */ void ActionTable::setAction( int ordering, Action *action ) { /* Multi-insert in case specific instances of an action appear in a * transition more than once. */ insertMulti( ordering, action ); } /* Set all the action from another action table in this table. */ void ActionTable::setActions( const ActionTable &other ) { for ( ActionTable::Iter action = other; action.lte(); action++ ) insertMulti( action->key, action->value ); } void ActionTable::setActions( int *orderings, Action **actions, int nActs ) { for ( int a = 0; a < nActs; a++ ) insertMulti( orderings[a], actions[a] ); } bool ActionTable::hasAction( Action *action ) { for ( int a = 0; a < length(); a++ ) { if ( data[a].value == action ) return true; } return false; } /* Insert an action into an action table. */ void LmActionTable::setAction( int ordering, LongestMatchPart *action ) { /* Multi-insert in case specific instances of an action appear in a * transition more than once. */ insertMulti( ordering, action ); } /* Set all the action from another action table in this table. */ void LmActionTable::setActions( const LmActionTable &other ) { for ( LmActionTable::Iter action = other; action.lte(); action++ ) insertMulti( action->key, action->value ); } void ErrActionTable::setAction( int ordering, Action *action, int transferPoint ) { insertMulti( ErrActionTableEl( action, ordering, transferPoint ) ); } void ErrActionTable::setActions( const ErrActionTable &other ) { for ( ErrActionTable::Iter act = other; act.lte(); act++ ) insertMulti( ErrActionTableEl( act->action, act->ordering, act->transferPoint ) ); } /* Insert a priority into this priority table. Looks out for priorities on * duplicate keys. */ void PriorTable::setPrior( int ordering, PriorDesc *desc ) { PriorEl *lastHit = 0; PriorEl *insed = insert( PriorEl(ordering, desc), &lastHit ); if ( insed == 0 ) { /* This already has a priority on the same key as desc. Overwrite the * priority if the ordering is larger (later in time). */ if ( ordering >= lastHit->ordering ) *lastHit = PriorEl( ordering, desc ); } } /* Set all the priorities from a priorTable in this table. */ void PriorTable::setPriors( const PriorTable &other ) { /* Loop src priorities once to overwrite duplicates. */ PriorTable::Iter priorIt = other; for ( ; priorIt.lte(); priorIt++ ) setPrior( priorIt->ordering, priorIt->desc ); } /* Set the priority of starting transitions. Isolates the start state so it has * no other entry points, then sets the priorities of all the transitions out * of the start state. If the start state is final, then the outPrior of the * start state is also set. The idea is that a machine that accepts the null * string can still specify the starting trans prior for when it accepts the * null word. */ void FsmAp::startFsmPrior( int ordering, PriorDesc *prior ) { /* Make sure the start state has no other entry points. */ isolateStartState(); /* Walk all transitions out of the start state. */ for ( TransList::Iter trans = startState->outList; trans.lte(); trans++ ) { if ( trans->toState != 0 ) trans->priorTable.setPrior( ordering, prior ); } /* If the new start state is final then set the out priority. This follows * the same convention as setting start action in the out action table of * a final start state. */ if ( startState->stateBits & STB_ISFINAL ) startState->outPriorTable.setPrior( ordering, prior ); } /* Set the priority of all transitions in a graph. Walks all transition lists * and all def transitions. */ void FsmAp::allTransPrior( int ordering, PriorDesc *prior ) { /* Walk the list of all states. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Walk the out list of the state. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { if ( trans->toState != 0 ) trans->priorTable.setPrior( ordering, prior ); } } } /* Set the priority of all transitions that go into a final state. Note that if * any entry states are final, we will not be setting the priority of any * transitions that may go into those states in the future. The graph does not * support pending in transitions in the same way pending out transitions are * supported. */ void FsmAp::finishFsmPrior( int ordering, PriorDesc *prior ) { /* Walk all final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) { /* Walk all in transitions of the final state. */ for ( TransInList::Iter trans = (*state)->inList; trans.lte(); trans++ ) trans->priorTable.setPrior( ordering, prior ); } } /* Set the priority of any future out transitions that may be made going out of * this state machine. */ void FsmAp::leaveFsmPrior( int ordering, PriorDesc *prior ) { /* Set priority in all final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->outPriorTable.setPrior( ordering, prior ); } /* Set actions to execute on starting transitions. Isolates the start state * so it has no other entry points, then adds to the transition functions * of all the transitions out of the start state. If the start state is final, * then the func is also added to the start state's out func list. The idea is * that a machine that accepts the null string can execute a start func when it * matches the null word, which can only be done when leaving the start/final * state. */ void FsmAp::startFsmAction( int ordering, Action *action ) { /* Make sure the start state has no other entry points. */ isolateStartState(); /* Walk the start state's transitions, setting functions. */ for ( TransList::Iter trans = startState->outList; trans.lte(); trans++ ) { if ( trans->toState != 0 ) trans->actionTable.setAction( ordering, action ); } /* If start state is final then add the action to the out action table. * This means that when the null string is accepted the start action will * not be bypassed. */ if ( startState->stateBits & STB_ISFINAL ) startState->outActionTable.setAction( ordering, action ); } /* Set functions to execute on all transitions. Walks the out lists of all * states. */ void FsmAp::allTransAction( int ordering, Action *action ) { /* Walk all states. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Walk the out list of the state. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { if ( trans->toState != 0 ) trans->actionTable.setAction( ordering, action ); } } } /* Specify functions to execute upon entering final states. If the start state * is final we can't really specify a function to execute upon entering that * final state the first time. So function really means whenever entering a * final state from within the same fsm. */ void FsmAp::finishFsmAction( int ordering, Action *action ) { /* Walk all final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) { /* Walk the final state's in list. */ for ( TransInList::Iter trans = (*state)->inList; trans.lte(); trans++ ) trans->actionTable.setAction( ordering, action ); } } /* Add functions to any future out transitions that may be made going out of * this state machine. */ void FsmAp::leaveFsmAction( int ordering, Action *action ) { /* Insert the action in the outActionTable of all final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->outActionTable.setAction( ordering, action ); } /* Add functions to the longest match action table for constructing scanners. */ void FsmAp::longMatchAction( int ordering, LongestMatchPart *lmPart ) { /* Walk all final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) { /* Walk the final state's in list. */ for ( TransInList::Iter trans = (*state)->inList; trans.lte(); trans++ ) trans->lmActionTable.setAction( ordering, lmPart ); } } void FsmAp::fillGaps( StateAp *state ) { if ( state->outList.length() == 0 ) { /* Add the range on the lower and upper bound. */ attachNewTrans( state, 0, keyOps->minKey, keyOps->maxKey ); } else { TransList srcList; srcList.transfer( state->outList ); /* Check for a gap at the beginning. */ TransList::Iter trans = srcList, next; if ( keyOps->minKey < trans->lowKey ) { /* Make the high key and append. */ Key highKey = trans->lowKey; highKey.decrement(); attachNewTrans( state, 0, keyOps->minKey, highKey ); } /* Write the transition. */ next = trans.next(); state->outList.append( trans ); /* Keep the last high end. */ Key lastHigh = trans->highKey; /* Loop each source range. */ for ( trans = next; trans.lte(); trans = next ) { /* Make the next key following the last range. */ Key nextKey = lastHigh; nextKey.increment(); /* Check for a gap from last up to here. */ if ( nextKey < trans->lowKey ) { /* Make the high end of the range that fills the gap. */ Key highKey = trans->lowKey; highKey.decrement(); attachNewTrans( state, 0, nextKey, highKey ); } /* Reduce the transition. If it reduced to anything then add it. */ next = trans.next(); state->outList.append( trans ); /* Keep the last high end. */ lastHigh = trans->highKey; } /* Now check for a gap on the end to fill. */ if ( lastHigh < keyOps->maxKey ) { /* Get a copy of the default. */ lastHigh.increment(); attachNewTrans( state, 0, lastHigh, keyOps->maxKey ); } } } void FsmAp::setErrorActions( StateAp *state, const ActionTable &other ) { /* Fill any gaps in the out list with an error transition. */ fillGaps( state ); /* Set error transitions in the transitions that go to error. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { if ( trans->toState == 0 ) trans->actionTable.setActions( other ); } } void FsmAp::setErrorAction( StateAp *state, int ordering, Action *action ) { /* Fill any gaps in the out list with an error transition. */ fillGaps( state ); /* Set error transitions in the transitions that go to error. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { if ( trans->toState == 0 ) trans->actionTable.setAction( ordering, action ); } } /* Give a target state for error transitions. */ void FsmAp::setErrorTarget( StateAp *state, StateAp *target, int *orderings, Action **actions, int nActs ) { /* Fill any gaps in the out list with an error transition. */ fillGaps( state ); /* Set error target in the transitions that go to error. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { if ( trans->toState == 0 ) { /* The trans goes to error, redirect it. */ redirectErrorTrans( trans->fromState, target, trans ); trans->actionTable.setActions( orderings, actions, nActs ); } } } void FsmAp::transferOutActions( StateAp *state ) { for ( ActionTable::Iter act = state->outActionTable; act.lte(); act++ ) state->eofActionTable.setAction( act->key, act->value ); state->outActionTable.empty(); } void FsmAp::transferErrorActions( StateAp *state, int transferPoint ) { for ( int i = 0; i < state->errActionTable.length(); ) { ErrActionTableEl *act = state->errActionTable.data + i; if ( act->transferPoint == transferPoint ) { /* Transfer the error action and remove it. */ setErrorAction( state, act->ordering, act->action ); if ( ! state->isFinState() ) state->eofActionTable.setAction( act->ordering, act->action ); state->errActionTable.vremove( i ); } else { /* Not transfering and deleting, skip over the item. */ i += 1; } } } /* Set error actions in the start state. */ void FsmAp::startErrorAction( int ordering, Action *action, int transferPoint ) { /* Make sure the start state has no other entry points. */ isolateStartState(); /* Add the actions. */ startState->errActionTable.setAction( ordering, action, transferPoint ); } /* Set error actions in all states where there is a transition out. */ void FsmAp::allErrorAction( int ordering, Action *action, int transferPoint ) { /* Insert actions in the error action table of all states. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) state->errActionTable.setAction( ordering, action, transferPoint ); } /* Set error actions in final states. */ void FsmAp::finalErrorAction( int ordering, Action *action, int transferPoint ) { /* Add the action to the error table of final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->errActionTable.setAction( ordering, action, transferPoint ); } void FsmAp::notStartErrorAction( int ordering, Action *action, int transferPoint ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState ) state->errActionTable.setAction( ordering, action, transferPoint ); } } void FsmAp::notFinalErrorAction( int ordering, Action *action, int transferPoint ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( ! state->isFinState() ) state->errActionTable.setAction( ordering, action, transferPoint ); } } /* Set error actions in the states that have transitions into a final state. */ void FsmAp::middleErrorAction( int ordering, Action *action, int transferPoint ) { /* Isolate the start state in case it is reachable from in inside the * machine, in which case we don't want it set. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState && ! state->isFinState() ) state->errActionTable.setAction( ordering, action, transferPoint ); } } /* Set EOF actions in the start state. */ void FsmAp::startEOFAction( int ordering, Action *action ) { /* Make sure the start state has no other entry points. */ isolateStartState(); /* Add the actions. */ startState->eofActionTable.setAction( ordering, action ); } /* Set EOF actions in all states where there is a transition out. */ void FsmAp::allEOFAction( int ordering, Action *action ) { /* Insert actions in the EOF action table of all states. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) state->eofActionTable.setAction( ordering, action ); } /* Set EOF actions in final states. */ void FsmAp::finalEOFAction( int ordering, Action *action ) { /* Add the action to the error table of final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->eofActionTable.setAction( ordering, action ); } void FsmAp::notStartEOFAction( int ordering, Action *action ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState ) state->eofActionTable.setAction( ordering, action ); } } void FsmAp::notFinalEOFAction( int ordering, Action *action ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( ! state->isFinState() ) state->eofActionTable.setAction( ordering, action ); } } /* Set EOF actions in the states that have transitions into a final state. */ void FsmAp::middleEOFAction( int ordering, Action *action ) { /* Set the actions in all states that are not the start state and not final. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState && ! state->isFinState() ) state->eofActionTable.setAction( ordering, action ); } } /* * Set To State Actions. */ /* Set to state actions in the start state. */ void FsmAp::startToStateAction( int ordering, Action *action ) { /* Make sure the start state has no other entry points. */ isolateStartState(); startState->toStateActionTable.setAction( ordering, action ); } /* Set to state actions in all states. */ void FsmAp::allToStateAction( int ordering, Action *action ) { /* Insert the action on all states. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) state->toStateActionTable.setAction( ordering, action ); } /* Set to state actions in final states. */ void FsmAp::finalToStateAction( int ordering, Action *action ) { /* Add the action to the error table of final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->toStateActionTable.setAction( ordering, action ); } void FsmAp::notStartToStateAction( int ordering, Action *action ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState ) state->toStateActionTable.setAction( ordering, action ); } } void FsmAp::notFinalToStateAction( int ordering, Action *action ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( ! state->isFinState() ) state->toStateActionTable.setAction( ordering, action ); } } /* Set to state actions in states that are not final and not the start state. */ void FsmAp::middleToStateAction( int ordering, Action *action ) { /* Set the action in all states that are not the start state and not final. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState && ! state->isFinState() ) state->toStateActionTable.setAction( ordering, action ); } } /* * Set From State Actions. */ void FsmAp::startFromStateAction( int ordering, Action *action ) { /* Make sure the start state has no other entry points. */ isolateStartState(); startState->fromStateActionTable.setAction( ordering, action ); } void FsmAp::allFromStateAction( int ordering, Action *action ) { /* Insert the action on all states. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) state->fromStateActionTable.setAction( ordering, action ); } void FsmAp::finalFromStateAction( int ordering, Action *action ) { /* Add the action to the error table of final states. */ for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->fromStateActionTable.setAction( ordering, action ); } void FsmAp::notStartFromStateAction( int ordering, Action *action ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState ) state->fromStateActionTable.setAction( ordering, action ); } } void FsmAp::notFinalFromStateAction( int ordering, Action *action ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( ! state->isFinState() ) state->fromStateActionTable.setAction( ordering, action ); } } void FsmAp::middleFromStateAction( int ordering, Action *action ) { /* Set the action in all states that are not the start state and not final. */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { if ( state != startState && ! state->isFinState() ) state->fromStateActionTable.setAction( ordering, action ); } } /* Shift the function ordering of the start transitions to start * at fromOrder and increase in units of 1. Useful before staring. * Returns the maximum number of order numbers used. */ int FsmAp::shiftStartActionOrder( int fromOrder ) { int maxUsed = 0; /* Walk the start state's transitions, shifting function ordering. */ for ( TransList::Iter trans = startState->outList; trans.lte(); trans++ ) { /* Walk the function data for the transition and set the keys to * increasing values starting at fromOrder. */ int curFromOrder = fromOrder; ActionTable::Iter action = trans->actionTable; for ( ; action.lte(); action++ ) action->key = curFromOrder++; /* Keep track of the max number of orders used. */ if ( curFromOrder - fromOrder > maxUsed ) maxUsed = curFromOrder - fromOrder; } return maxUsed; } /* Remove all priorities. */ void FsmAp::clearAllPriorities() { for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Clear out priority data. */ state->outPriorTable.empty(); /* Clear transition data from the out transitions. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) trans->priorTable.empty(); } } /* Zeros out the function ordering keys. This may be called before minimization * when it is known that no more fsm operations are going to be done. This * will achieve greater reduction as states will not be separated on the basis * of function ordering. */ void FsmAp::nullActionKeys( ) { /* For each state... */ for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Walk the transitions for the state. */ for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { /* Walk the action table for the transition. */ for ( ActionTable::Iter action = trans->actionTable; action.lte(); action++ ) action->key = 0; /* Walk the action table for the transition. */ for ( LmActionTable::Iter action = trans->lmActionTable; action.lte(); action++ ) action->key = 0; } /* Null the action keys of the to state action table. */ for ( ActionTable::Iter action = state->toStateActionTable; action.lte(); action++ ) action->key = 0; /* Null the action keys of the from state action table. */ for ( ActionTable::Iter action = state->fromStateActionTable; action.lte(); action++ ) action->key = 0; /* Null the action keys of the out transtions. */ for ( ActionTable::Iter action = state->outActionTable; action.lte(); action++ ) action->key = 0; /* Null the action keys of the error action table. */ for ( ErrActionTable::Iter action = state->errActionTable; action.lte(); action++ ) action->ordering = 0; /* Null the action keys eof action table. */ for ( ActionTable::Iter action = state->eofActionTable; action.lte(); action++ ) action->key = 0; } } /* Walk the list of states and verify that non final states do not have out * data, that all stateBits are cleared, and that there are no states with * zero foreign in transitions. */ void FsmAp::verifyStates() { for ( StateList::Iter state = stateList; state.lte(); state++ ) { /* Non final states should not have leaving data. */ if ( ! (state->stateBits & STB_ISFINAL) ) { assert( state->outActionTable.length() == 0 ); assert( state->outCondSet.length() == 0 ); assert( state->outPriorTable.length() == 0 ); } /* Data used in algorithms should be cleared. */ assert( (state->stateBits & STB_BOTH) == 0 ); assert( state->foreignInTrans > 0 ); } } /* Compare two transitions according to their relative priority. Since the * base transition has no priority associated with it, the default is to * return equal. */ int FsmAp::comparePrior( const PriorTable &priorTable1, const PriorTable &priorTable2 ) { /* Looking for differing priorities on same keys. Need to concurrently * scan the priority lists. */ PriorTable::Iter pd1 = priorTable1; PriorTable::Iter pd2 = priorTable2; while ( pd1.lte() && pd2.lte() ) { /* Check keys. */ if ( pd1->desc->key < pd2->desc->key ) pd1.increment(); else if ( pd1->desc->key > pd2->desc->key ) pd2.increment(); /* Keys are the same, check priorities. */ else if ( pd1->desc->priority < pd2->desc->priority ) return -1; else if ( pd1->desc->priority > pd2->desc->priority ) return 1; else { /* Keys and priorities are equal, advance both. */ pd1.increment(); pd2.increment(); } } /* No differing priorities on the same key. */ return 0; } /* Compares two transitions according to priority and functions. Pointers * should not be null. Does not consider to state or from state. Compare two * transitions according to the data contained in the transitions. Data means * any properties added to user transitions that may differentiate them. Since * the base transition has no data, the default is to return equal. */ int FsmAp::compareTransData( TransAp *trans1, TransAp *trans2 ) { /* Compare the prior table. */ int cmpRes = CmpPriorTable::compare( trans1->priorTable, trans2->priorTable ); if ( cmpRes != 0 ) return cmpRes; /* Compare longest match action tables. */ cmpRes = CmpLmActionTable::compare(trans1->lmActionTable, trans2->lmActionTable); if ( cmpRes != 0 ) return cmpRes; /* Compare action tables. */ return CmpActionTable::compare(trans1->actionTable, trans2->actionTable); } /* Callback invoked when another trans (or possibly this) is added into this * transition during the merging process. Draw in any properties of srcTrans * into this transition. AddInTrans is called when a new transitions is made * that will be a duplicate of another transition or a combination of several * other transitions. AddInTrans will be called for each transition that the * new transition is to represent. */ void FsmAp::addInTrans( TransAp *destTrans, TransAp *srcTrans ) { /* Protect against adding in from ourselves. */ if ( srcTrans == destTrans ) { /* Adding in ourselves, need to make a copy of the source transitions. * The priorities are not copied in as that would have no effect. */ destTrans->lmActionTable.setActions( LmActionTable(srcTrans->lmActionTable) ); destTrans->actionTable.setActions( ActionTable(srcTrans->actionTable) ); } else { /* Not a copy of ourself, get the functions and priorities. */ destTrans->lmActionTable.setActions( srcTrans->lmActionTable ); destTrans->actionTable.setActions( srcTrans->actionTable ); destTrans->priorTable.setPriors( srcTrans->priorTable ); } } /* Compare the properties of states that are embedded by users. Compares out * priorities, out transitions, to, from, out, error and eof action tables. */ int FsmAp::compareStateData( const StateAp *state1, const StateAp *state2 ) { /* Compare the out priority table. */ int cmpRes = CmpPriorTable:: compare( state1->outPriorTable, state2->outPriorTable ); if ( cmpRes != 0 ) return cmpRes; /* Test to state action tables. */ cmpRes = CmpActionTable::compare( state1->toStateActionTable, state2->toStateActionTable ); if ( cmpRes != 0 ) return cmpRes; /* Test from state action tables. */ cmpRes = CmpActionTable::compare( state1->fromStateActionTable, state2->fromStateActionTable ); if ( cmpRes != 0 ) return cmpRes; /* Test out action tables. */ cmpRes = CmpActionTable::compare( state1->outActionTable, state2->outActionTable ); if ( cmpRes != 0 ) return cmpRes; /* Test out condition sets. */ cmpRes = CmpOutCondSet::compare( state1->outCondSet, state2->outCondSet ); if ( cmpRes != 0 ) return cmpRes; /* Test out error action tables. */ cmpRes = CmpErrActionTable::compare( state1->errActionTable, state2->errActionTable ); if ( cmpRes != 0 ) return cmpRes; /* Test eof action tables. */ return CmpActionTable::compare( state1->eofActionTable, state2->eofActionTable ); } /* Invoked when a state looses its final state status and the leaving * transition embedding data should be deleted. */ void FsmAp::clearOutData( StateAp *state ) { /* Kill the out actions and priorities. */ state->outActionTable.empty(); state->outCondSet.empty(); state->outPriorTable.empty(); } bool FsmAp::hasOutData( StateAp *state ) { return ( state->outActionTable.length() > 0 || state->outCondSet.length() > 0 || state->outPriorTable.length() > 0 ); } /* * Setting Conditions. */ void logNewExpansion( Expansion *exp ); void logCondSpace( CondSpace *condSpace ); CondSpace *FsmAp::addCondSpace( const CondSet &condSet ) { CondSpace *condSpace = condData->condSpaceMap.find( condSet ); if ( condSpace == 0 ) { /* Do we have enough keyspace left? */ Size availableSpace = condData->lastCondKey.availableSpace(); Size neededSpace = (1 << condSet.length() ) * keyOps->alphSize(); if ( neededSpace > availableSpace ) throw FsmConstructFail( FsmConstructFail::CondNoKeySpace ); Key baseKey = condData->lastCondKey; baseKey.increment(); condData->lastCondKey += (1 << condSet.length() ) * keyOps->alphSize(); condSpace = new CondSpace( condSet ); condSpace->baseKey = baseKey; condData->condSpaceMap.insert( condSpace ); #ifdef LOG_CONDS cerr << "adding new condition space" << endl; cerr << " condition set: "; logCondSpace( condSpace ); cerr << endl; cerr << " baseKey: " << baseKey.getVal() << endl; #endif } return condSpace; } void FsmAp::startFsmCondition( Action *condAction, bool sense ) { /* Make sure the start state has no other entry points. */ isolateStartState(); embedCondition( startState, condAction, sense ); } void FsmAp::allTransCondition( Action *condAction, bool sense ) { for ( StateList::Iter state = stateList; state.lte(); state++ ) embedCondition( state, condAction, sense ); } void FsmAp::leaveFsmCondition( Action *condAction, bool sense ) { for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) (*state)->outCondSet.insert( OutCond( condAction, sense ) ); } ragel-6.10/ragel/gofgoto.cpp0000664000175000017500000001613113065111230012711 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "gofgoto.h" #include "redfsm.h" #include "gendata.h" #include "bstmap.h" using std::endl; std::ostream &GoFGotoCodeGen::EXEC_ACTIONS() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* We are at the start of a glob, write the case. */ out << "f" << redAct->actListId << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << TABS(1) << "goto _again" << endl; } } return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFGotoCodeGen::TO_STATE_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &GoFGotoCodeGen::FROM_STATE_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoFGotoCodeGen::EOF_ACTION_SWITCH( int level ) { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << TABS(level) << "case " << redAct->actListId+1 << ":" << endl; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); } } genLineDirective( out ); return out; } std::ostream &GoFGotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << TABS(2) << "case " << st->id << ":" << endl; /* Jump to the func. */ out << TABS(3) << "goto f" << st->eofAction->actListId << endl; } } return out; } unsigned int GoFGotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; return act; } unsigned int GoFGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; return act; } unsigned int GoFGotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; return act; } void GoFGotoCodeGen::writeData() { if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << endl; } STATE_IDS(); } void GoFGotoCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {" << endl; if ( redFsm->anyRegCurStateRef() ) out << " var _ps " << INT() << " = 0" << endl; if ( redFsm->anyConditions() ) out << " var _widec " << WIDE_ALPH_TYPE() << endl; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " == " << PE() << " {" << endl << " goto _test_eof" << endl << " }" << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } out << "_resume:" << endl; if ( redFsm->anyFromStateActions() ) { out << " switch " << FSA() << "[" << vCS() << "] {" << endl; FROM_STATE_ACTION_SWITCH(1); out << " }" << endl << endl; } out << " switch " << vCS() << " {" << endl; STATE_GOTOS(1); out << " }" << endl << endl; TRANSITIONS() << endl; if ( redFsm->anyRegActions() ) EXEC_ACTIONS() << endl; out << "_again:" << endl; if ( redFsm->anyToStateActions() ) { out << " switch " << TSA() << "[" << vCS() << "] {" << endl; TO_STATE_ACTION_SWITCH(1); out << " }" << endl << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } if ( !noEnd ) { out << " if " << P() << "++; " << P() << " != " << PE() << " {" << endl << " goto _resume" << endl << " }" << endl; } else { out << " " << P() << "++" << endl << " goto _resume" << endl; } if ( testEofUsed ) out << " _test_eof: {}" << endl; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << " {" << endl; if ( redFsm->anyEofTrans() ) { out << " switch " << vCS() << " {" << endl; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " case " << st->id << ":" << endl << " goto tr" << st->eofTrans->id << endl; } out << " }" << endl; } if ( redFsm->anyEofActions() ) { out << " switch " << EA() << "[" << vCS() << "] {" << endl; EOF_ACTION_SWITCH(2); out << " }" << endl; } out << " }" << endl << endl; } if ( outLabelUsed ) out << " _out: {}" << endl; out << " }" << endl; } ragel-6.10/ragel/gotablish.h0000664000175000017500000000347513065111230012675 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOTABLISH_H #define _GOTABLISH_H #include "gocodegen.h" class GoTablishCodeGen : public GoCodeGen { public: GoTablishCodeGen( ostream &out ) : GoCodeGen(out) {} protected: virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ); virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ); virtual void NEXT( ostream &ret, int nextDest, bool inFinish ); virtual void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); virtual void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); virtual void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); virtual void CURS( ostream &ret, bool inFinish ); virtual void TARGS( ostream &ret, bool inFinish, int targState ); virtual void RET( ostream &ret, bool inFinish ); virtual void BREAK( ostream &ret, int targState, bool csForced ); }; #endif ragel-6.10/ragel/Makefile.in0000664000175000017500000040173113065122656012630 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = ragel$(EXEEXT) subdir = ragel ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_ragel_OBJECTS = ragel-main.$(OBJEXT) ragel-parsetree.$(OBJEXT) \ ragel-parsedata.$(OBJEXT) ragel-fsmstate.$(OBJEXT) \ ragel-fsmbase.$(OBJEXT) ragel-fsmattach.$(OBJEXT) \ ragel-fsmmin.$(OBJEXT) ragel-fsmgraph.$(OBJEXT) \ ragel-fsmap.$(OBJEXT) ragel-rlscan.$(OBJEXT) \ ragel-rlparse.$(OBJEXT) ragel-inputdata.$(OBJEXT) \ ragel-common.$(OBJEXT) ragel-redfsm.$(OBJEXT) \ ragel-gendata.$(OBJEXT) ragel-cdcodegen.$(OBJEXT) \ ragel-cdtable.$(OBJEXT) ragel-cdftable.$(OBJEXT) \ ragel-cdflat.$(OBJEXT) ragel-cdfflat.$(OBJEXT) \ ragel-cdgoto.$(OBJEXT) ragel-cdfgoto.$(OBJEXT) \ ragel-cdipgoto.$(OBJEXT) ragel-cdsplit.$(OBJEXT) \ ragel-javacodegen.$(OBJEXT) ragel-rubycodegen.$(OBJEXT) \ ragel-rubytable.$(OBJEXT) ragel-rubyftable.$(OBJEXT) \ ragel-rubyflat.$(OBJEXT) ragel-rubyfflat.$(OBJEXT) \ ragel-rbxgoto.$(OBJEXT) ragel-cscodegen.$(OBJEXT) \ ragel-cstable.$(OBJEXT) ragel-csftable.$(OBJEXT) \ ragel-csflat.$(OBJEXT) ragel-csfflat.$(OBJEXT) \ ragel-csgoto.$(OBJEXT) ragel-csfgoto.$(OBJEXT) \ ragel-csipgoto.$(OBJEXT) ragel-cssplit.$(OBJEXT) \ ragel-dotcodegen.$(OBJEXT) ragel-xmlcodegen.$(OBJEXT) \ ragel-gocodegen.$(OBJEXT) ragel-gotable.$(OBJEXT) \ ragel-goftable.$(OBJEXT) ragel-goflat.$(OBJEXT) \ ragel-gofflat.$(OBJEXT) ragel-gogoto.$(OBJEXT) \ ragel-gofgoto.$(OBJEXT) ragel-goipgoto.$(OBJEXT) \ ragel-gotablish.$(OBJEXT) ragel-mlcodegen.$(OBJEXT) \ ragel-mltable.$(OBJEXT) ragel-mlftable.$(OBJEXT) \ ragel-mlflat.$(OBJEXT) ragel-mlfflat.$(OBJEXT) \ ragel-mlgoto.$(OBJEXT) ragel-mlfgoto.$(OBJEXT) ragel_OBJECTS = $(am_ragel_OBJECTS) ragel_LDADD = $(LDADD) ragel_LINK = $(CXXLD) $(ragel_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(ragel_SOURCES) DIST_SOURCES = $(ragel_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EXEEXT = @EXEEXT@ FIG2DEV = @FIG2DEV@ GDC = @GDC@ GMCS = @GMCS@ GOBIN = @GOBIN@ GOBJC = @GOBJC@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVAC = @JAVAC@ KELBT = @KELBT@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PUBDATE = @PUBDATE@ RAGEL = @RAGEL@ RANLIB = @RANLIB@ RUBY = @RUBY@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TXL = @TXL@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = -I$(top_srcdir)/aapl ragel_CXXFLAGS = -Wall ragel_SOURCES = \ buffer.h cdgoto.h cscodegen.h csipgoto.h inputdata.h rbxgoto.h \ rubyflat.h cdcodegen.h cdipgoto.h csfflat.h cssplit.h javacodegen.h \ redfsm.h rubyftable.h cdfflat.h cdsplit.h csfgoto.h cstable.h \ parsedata.h rlparse.h rubytable.h cdfgoto.h cdtable.h csflat.h \ dotcodegen.h parsetree.h rlscan.h version.h cdflat.h common.h \ csftable.h fsmgraph.h pcheck.h rubycodegen.h xmlcodegen.h cdftable.h \ csgoto.h gendata.h ragel.h rubyfflat.h \ gocodegen.h gotable.h goftable.h goflat.h gofflat.h gogoto.h gofgoto.h \ goipgoto.h gotablish.h \ mlcodegen.h mltable.h mlftable.h mlflat.h mlfflat.h mlgoto.h mlfgoto.h \ main.cpp parsetree.cpp parsedata.cpp fsmstate.cpp fsmbase.cpp \ fsmattach.cpp fsmmin.cpp fsmgraph.cpp fsmap.cpp rlscan.cpp rlparse.cpp \ inputdata.cpp common.cpp redfsm.cpp gendata.cpp cdcodegen.cpp \ cdtable.cpp cdftable.cpp cdflat.cpp cdfflat.cpp cdgoto.cpp cdfgoto.cpp \ cdipgoto.cpp cdsplit.cpp javacodegen.cpp rubycodegen.cpp rubytable.cpp \ rubyftable.cpp rubyflat.cpp rubyfflat.cpp rbxgoto.cpp cscodegen.cpp \ cstable.cpp csftable.cpp csflat.cpp csfflat.cpp csgoto.cpp csfgoto.cpp \ csipgoto.cpp cssplit.cpp dotcodegen.cpp xmlcodegen.cpp \ gocodegen.cpp gotable.cpp goftable.cpp goflat.cpp gofflat.cpp gogoto.cpp gofgoto.cpp \ goipgoto.cpp gotablish.cpp \ mlcodegen.cpp mltable.cpp mlftable.cpp mlflat.cpp mlfflat.cpp mlgoto.cpp mlfgoto.cpp BUILT_SOURCES = \ rlscan.cpp rlparse.h rlparse.cpp version.h EXTRA_DIST = rlscan.rl rlparse.kh rlparse.kl @BUILD_PARSERS_TRUE@CLEANFILES = \ @BUILD_PARSERS_TRUE@ rlscan.cpp rlparse.h rlparse.cpp all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .cpp .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ragel/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign ragel/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status ragel/config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) ragel$(EXEEXT): $(ragel_OBJECTS) $(ragel_DEPENDENCIES) $(EXTRA_ragel_DEPENDENCIES) @rm -f ragel$(EXEEXT) $(AM_V_CXXLD)$(ragel_LINK) $(ragel_OBJECTS) $(ragel_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdcodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdfflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdfgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdftable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdipgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdsplit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cdtable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cscodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-csfflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-csfgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-csflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-csftable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-csgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-csipgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cssplit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-cstable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-dotcodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-fsmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-fsmattach.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-fsmbase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-fsmgraph.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-fsmmin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-fsmstate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gendata.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gocodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gofflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gofgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-goflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-goftable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gogoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-goipgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gotable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-gotablish.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-inputdata.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-javacodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mlcodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mlfflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mlfgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mlflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mlftable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mlgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-mltable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-parsedata.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-parsetree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rbxgoto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-redfsm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rlparse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rlscan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rubycodegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rubyfflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rubyflat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rubyftable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-rubytable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ragel-xmlcodegen.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ragel-main.o: main.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-main.o -MD -MP -MF $(DEPDIR)/ragel-main.Tpo -c -o ragel-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-main.Tpo $(DEPDIR)/ragel-main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='main.cpp' object='ragel-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp ragel-main.obj: main.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-main.obj -MD -MP -MF $(DEPDIR)/ragel-main.Tpo -c -o ragel-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-main.Tpo $(DEPDIR)/ragel-main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='main.cpp' object='ragel-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi` ragel-parsetree.o: parsetree.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-parsetree.o -MD -MP -MF $(DEPDIR)/ragel-parsetree.Tpo -c -o ragel-parsetree.o `test -f 'parsetree.cpp' || echo '$(srcdir)/'`parsetree.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-parsetree.Tpo $(DEPDIR)/ragel-parsetree.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parsetree.cpp' object='ragel-parsetree.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-parsetree.o `test -f 'parsetree.cpp' || echo '$(srcdir)/'`parsetree.cpp ragel-parsetree.obj: parsetree.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-parsetree.obj -MD -MP -MF $(DEPDIR)/ragel-parsetree.Tpo -c -o ragel-parsetree.obj `if test -f 'parsetree.cpp'; then $(CYGPATH_W) 'parsetree.cpp'; else $(CYGPATH_W) '$(srcdir)/parsetree.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-parsetree.Tpo $(DEPDIR)/ragel-parsetree.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parsetree.cpp' object='ragel-parsetree.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-parsetree.obj `if test -f 'parsetree.cpp'; then $(CYGPATH_W) 'parsetree.cpp'; else $(CYGPATH_W) '$(srcdir)/parsetree.cpp'; fi` ragel-parsedata.o: parsedata.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-parsedata.o -MD -MP -MF $(DEPDIR)/ragel-parsedata.Tpo -c -o ragel-parsedata.o `test -f 'parsedata.cpp' || echo '$(srcdir)/'`parsedata.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-parsedata.Tpo $(DEPDIR)/ragel-parsedata.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parsedata.cpp' object='ragel-parsedata.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-parsedata.o `test -f 'parsedata.cpp' || echo '$(srcdir)/'`parsedata.cpp ragel-parsedata.obj: parsedata.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-parsedata.obj -MD -MP -MF $(DEPDIR)/ragel-parsedata.Tpo -c -o ragel-parsedata.obj `if test -f 'parsedata.cpp'; then $(CYGPATH_W) 'parsedata.cpp'; else $(CYGPATH_W) '$(srcdir)/parsedata.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-parsedata.Tpo $(DEPDIR)/ragel-parsedata.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parsedata.cpp' object='ragel-parsedata.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-parsedata.obj `if test -f 'parsedata.cpp'; then $(CYGPATH_W) 'parsedata.cpp'; else $(CYGPATH_W) '$(srcdir)/parsedata.cpp'; fi` ragel-fsmstate.o: fsmstate.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmstate.o -MD -MP -MF $(DEPDIR)/ragel-fsmstate.Tpo -c -o ragel-fsmstate.o `test -f 'fsmstate.cpp' || echo '$(srcdir)/'`fsmstate.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmstate.Tpo $(DEPDIR)/ragel-fsmstate.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmstate.cpp' object='ragel-fsmstate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmstate.o `test -f 'fsmstate.cpp' || echo '$(srcdir)/'`fsmstate.cpp ragel-fsmstate.obj: fsmstate.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmstate.obj -MD -MP -MF $(DEPDIR)/ragel-fsmstate.Tpo -c -o ragel-fsmstate.obj `if test -f 'fsmstate.cpp'; then $(CYGPATH_W) 'fsmstate.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmstate.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmstate.Tpo $(DEPDIR)/ragel-fsmstate.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmstate.cpp' object='ragel-fsmstate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmstate.obj `if test -f 'fsmstate.cpp'; then $(CYGPATH_W) 'fsmstate.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmstate.cpp'; fi` ragel-fsmbase.o: fsmbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmbase.o -MD -MP -MF $(DEPDIR)/ragel-fsmbase.Tpo -c -o ragel-fsmbase.o `test -f 'fsmbase.cpp' || echo '$(srcdir)/'`fsmbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmbase.Tpo $(DEPDIR)/ragel-fsmbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmbase.cpp' object='ragel-fsmbase.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmbase.o `test -f 'fsmbase.cpp' || echo '$(srcdir)/'`fsmbase.cpp ragel-fsmbase.obj: fsmbase.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmbase.obj -MD -MP -MF $(DEPDIR)/ragel-fsmbase.Tpo -c -o ragel-fsmbase.obj `if test -f 'fsmbase.cpp'; then $(CYGPATH_W) 'fsmbase.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmbase.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmbase.Tpo $(DEPDIR)/ragel-fsmbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmbase.cpp' object='ragel-fsmbase.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmbase.obj `if test -f 'fsmbase.cpp'; then $(CYGPATH_W) 'fsmbase.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmbase.cpp'; fi` ragel-fsmattach.o: fsmattach.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmattach.o -MD -MP -MF $(DEPDIR)/ragel-fsmattach.Tpo -c -o ragel-fsmattach.o `test -f 'fsmattach.cpp' || echo '$(srcdir)/'`fsmattach.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmattach.Tpo $(DEPDIR)/ragel-fsmattach.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmattach.cpp' object='ragel-fsmattach.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmattach.o `test -f 'fsmattach.cpp' || echo '$(srcdir)/'`fsmattach.cpp ragel-fsmattach.obj: fsmattach.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmattach.obj -MD -MP -MF $(DEPDIR)/ragel-fsmattach.Tpo -c -o ragel-fsmattach.obj `if test -f 'fsmattach.cpp'; then $(CYGPATH_W) 'fsmattach.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmattach.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmattach.Tpo $(DEPDIR)/ragel-fsmattach.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmattach.cpp' object='ragel-fsmattach.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmattach.obj `if test -f 'fsmattach.cpp'; then $(CYGPATH_W) 'fsmattach.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmattach.cpp'; fi` ragel-fsmmin.o: fsmmin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmmin.o -MD -MP -MF $(DEPDIR)/ragel-fsmmin.Tpo -c -o ragel-fsmmin.o `test -f 'fsmmin.cpp' || echo '$(srcdir)/'`fsmmin.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmmin.Tpo $(DEPDIR)/ragel-fsmmin.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmmin.cpp' object='ragel-fsmmin.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmmin.o `test -f 'fsmmin.cpp' || echo '$(srcdir)/'`fsmmin.cpp ragel-fsmmin.obj: fsmmin.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmmin.obj -MD -MP -MF $(DEPDIR)/ragel-fsmmin.Tpo -c -o ragel-fsmmin.obj `if test -f 'fsmmin.cpp'; then $(CYGPATH_W) 'fsmmin.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmmin.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmmin.Tpo $(DEPDIR)/ragel-fsmmin.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmmin.cpp' object='ragel-fsmmin.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmmin.obj `if test -f 'fsmmin.cpp'; then $(CYGPATH_W) 'fsmmin.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmmin.cpp'; fi` ragel-fsmgraph.o: fsmgraph.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmgraph.o -MD -MP -MF $(DEPDIR)/ragel-fsmgraph.Tpo -c -o ragel-fsmgraph.o `test -f 'fsmgraph.cpp' || echo '$(srcdir)/'`fsmgraph.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmgraph.Tpo $(DEPDIR)/ragel-fsmgraph.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmgraph.cpp' object='ragel-fsmgraph.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmgraph.o `test -f 'fsmgraph.cpp' || echo '$(srcdir)/'`fsmgraph.cpp ragel-fsmgraph.obj: fsmgraph.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmgraph.obj -MD -MP -MF $(DEPDIR)/ragel-fsmgraph.Tpo -c -o ragel-fsmgraph.obj `if test -f 'fsmgraph.cpp'; then $(CYGPATH_W) 'fsmgraph.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmgraph.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmgraph.Tpo $(DEPDIR)/ragel-fsmgraph.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmgraph.cpp' object='ragel-fsmgraph.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmgraph.obj `if test -f 'fsmgraph.cpp'; then $(CYGPATH_W) 'fsmgraph.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmgraph.cpp'; fi` ragel-fsmap.o: fsmap.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmap.o -MD -MP -MF $(DEPDIR)/ragel-fsmap.Tpo -c -o ragel-fsmap.o `test -f 'fsmap.cpp' || echo '$(srcdir)/'`fsmap.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmap.Tpo $(DEPDIR)/ragel-fsmap.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmap.cpp' object='ragel-fsmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmap.o `test -f 'fsmap.cpp' || echo '$(srcdir)/'`fsmap.cpp ragel-fsmap.obj: fsmap.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-fsmap.obj -MD -MP -MF $(DEPDIR)/ragel-fsmap.Tpo -c -o ragel-fsmap.obj `if test -f 'fsmap.cpp'; then $(CYGPATH_W) 'fsmap.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmap.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-fsmap.Tpo $(DEPDIR)/ragel-fsmap.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='fsmap.cpp' object='ragel-fsmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-fsmap.obj `if test -f 'fsmap.cpp'; then $(CYGPATH_W) 'fsmap.cpp'; else $(CYGPATH_W) '$(srcdir)/fsmap.cpp'; fi` ragel-rlscan.o: rlscan.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rlscan.o -MD -MP -MF $(DEPDIR)/ragel-rlscan.Tpo -c -o ragel-rlscan.o `test -f 'rlscan.cpp' || echo '$(srcdir)/'`rlscan.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rlscan.Tpo $(DEPDIR)/ragel-rlscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rlscan.cpp' object='ragel-rlscan.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rlscan.o `test -f 'rlscan.cpp' || echo '$(srcdir)/'`rlscan.cpp ragel-rlscan.obj: rlscan.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rlscan.obj -MD -MP -MF $(DEPDIR)/ragel-rlscan.Tpo -c -o ragel-rlscan.obj `if test -f 'rlscan.cpp'; then $(CYGPATH_W) 'rlscan.cpp'; else $(CYGPATH_W) '$(srcdir)/rlscan.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rlscan.Tpo $(DEPDIR)/ragel-rlscan.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rlscan.cpp' object='ragel-rlscan.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rlscan.obj `if test -f 'rlscan.cpp'; then $(CYGPATH_W) 'rlscan.cpp'; else $(CYGPATH_W) '$(srcdir)/rlscan.cpp'; fi` ragel-rlparse.o: rlparse.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rlparse.o -MD -MP -MF $(DEPDIR)/ragel-rlparse.Tpo -c -o ragel-rlparse.o `test -f 'rlparse.cpp' || echo '$(srcdir)/'`rlparse.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rlparse.Tpo $(DEPDIR)/ragel-rlparse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rlparse.cpp' object='ragel-rlparse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rlparse.o `test -f 'rlparse.cpp' || echo '$(srcdir)/'`rlparse.cpp ragel-rlparse.obj: rlparse.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rlparse.obj -MD -MP -MF $(DEPDIR)/ragel-rlparse.Tpo -c -o ragel-rlparse.obj `if test -f 'rlparse.cpp'; then $(CYGPATH_W) 'rlparse.cpp'; else $(CYGPATH_W) '$(srcdir)/rlparse.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rlparse.Tpo $(DEPDIR)/ragel-rlparse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rlparse.cpp' object='ragel-rlparse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rlparse.obj `if test -f 'rlparse.cpp'; then $(CYGPATH_W) 'rlparse.cpp'; else $(CYGPATH_W) '$(srcdir)/rlparse.cpp'; fi` ragel-inputdata.o: inputdata.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-inputdata.o -MD -MP -MF $(DEPDIR)/ragel-inputdata.Tpo -c -o ragel-inputdata.o `test -f 'inputdata.cpp' || echo '$(srcdir)/'`inputdata.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-inputdata.Tpo $(DEPDIR)/ragel-inputdata.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='inputdata.cpp' object='ragel-inputdata.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-inputdata.o `test -f 'inputdata.cpp' || echo '$(srcdir)/'`inputdata.cpp ragel-inputdata.obj: inputdata.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-inputdata.obj -MD -MP -MF $(DEPDIR)/ragel-inputdata.Tpo -c -o ragel-inputdata.obj `if test -f 'inputdata.cpp'; then $(CYGPATH_W) 'inputdata.cpp'; else $(CYGPATH_W) '$(srcdir)/inputdata.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-inputdata.Tpo $(DEPDIR)/ragel-inputdata.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='inputdata.cpp' object='ragel-inputdata.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-inputdata.obj `if test -f 'inputdata.cpp'; then $(CYGPATH_W) 'inputdata.cpp'; else $(CYGPATH_W) '$(srcdir)/inputdata.cpp'; fi` ragel-common.o: common.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-common.o -MD -MP -MF $(DEPDIR)/ragel-common.Tpo -c -o ragel-common.o `test -f 'common.cpp' || echo '$(srcdir)/'`common.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-common.Tpo $(DEPDIR)/ragel-common.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common.cpp' object='ragel-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-common.o `test -f 'common.cpp' || echo '$(srcdir)/'`common.cpp ragel-common.obj: common.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-common.obj -MD -MP -MF $(DEPDIR)/ragel-common.Tpo -c -o ragel-common.obj `if test -f 'common.cpp'; then $(CYGPATH_W) 'common.cpp'; else $(CYGPATH_W) '$(srcdir)/common.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-common.Tpo $(DEPDIR)/ragel-common.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='common.cpp' object='ragel-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-common.obj `if test -f 'common.cpp'; then $(CYGPATH_W) 'common.cpp'; else $(CYGPATH_W) '$(srcdir)/common.cpp'; fi` ragel-redfsm.o: redfsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-redfsm.o -MD -MP -MF $(DEPDIR)/ragel-redfsm.Tpo -c -o ragel-redfsm.o `test -f 'redfsm.cpp' || echo '$(srcdir)/'`redfsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-redfsm.Tpo $(DEPDIR)/ragel-redfsm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='redfsm.cpp' object='ragel-redfsm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-redfsm.o `test -f 'redfsm.cpp' || echo '$(srcdir)/'`redfsm.cpp ragel-redfsm.obj: redfsm.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-redfsm.obj -MD -MP -MF $(DEPDIR)/ragel-redfsm.Tpo -c -o ragel-redfsm.obj `if test -f 'redfsm.cpp'; then $(CYGPATH_W) 'redfsm.cpp'; else $(CYGPATH_W) '$(srcdir)/redfsm.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-redfsm.Tpo $(DEPDIR)/ragel-redfsm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='redfsm.cpp' object='ragel-redfsm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-redfsm.obj `if test -f 'redfsm.cpp'; then $(CYGPATH_W) 'redfsm.cpp'; else $(CYGPATH_W) '$(srcdir)/redfsm.cpp'; fi` ragel-gendata.o: gendata.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gendata.o -MD -MP -MF $(DEPDIR)/ragel-gendata.Tpo -c -o ragel-gendata.o `test -f 'gendata.cpp' || echo '$(srcdir)/'`gendata.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gendata.Tpo $(DEPDIR)/ragel-gendata.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gendata.cpp' object='ragel-gendata.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gendata.o `test -f 'gendata.cpp' || echo '$(srcdir)/'`gendata.cpp ragel-gendata.obj: gendata.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gendata.obj -MD -MP -MF $(DEPDIR)/ragel-gendata.Tpo -c -o ragel-gendata.obj `if test -f 'gendata.cpp'; then $(CYGPATH_W) 'gendata.cpp'; else $(CYGPATH_W) '$(srcdir)/gendata.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gendata.Tpo $(DEPDIR)/ragel-gendata.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gendata.cpp' object='ragel-gendata.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gendata.obj `if test -f 'gendata.cpp'; then $(CYGPATH_W) 'gendata.cpp'; else $(CYGPATH_W) '$(srcdir)/gendata.cpp'; fi` ragel-cdcodegen.o: cdcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdcodegen.o -MD -MP -MF $(DEPDIR)/ragel-cdcodegen.Tpo -c -o ragel-cdcodegen.o `test -f 'cdcodegen.cpp' || echo '$(srcdir)/'`cdcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdcodegen.Tpo $(DEPDIR)/ragel-cdcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdcodegen.cpp' object='ragel-cdcodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdcodegen.o `test -f 'cdcodegen.cpp' || echo '$(srcdir)/'`cdcodegen.cpp ragel-cdcodegen.obj: cdcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdcodegen.obj -MD -MP -MF $(DEPDIR)/ragel-cdcodegen.Tpo -c -o ragel-cdcodegen.obj `if test -f 'cdcodegen.cpp'; then $(CYGPATH_W) 'cdcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/cdcodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdcodegen.Tpo $(DEPDIR)/ragel-cdcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdcodegen.cpp' object='ragel-cdcodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdcodegen.obj `if test -f 'cdcodegen.cpp'; then $(CYGPATH_W) 'cdcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/cdcodegen.cpp'; fi` ragel-cdtable.o: cdtable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdtable.o -MD -MP -MF $(DEPDIR)/ragel-cdtable.Tpo -c -o ragel-cdtable.o `test -f 'cdtable.cpp' || echo '$(srcdir)/'`cdtable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdtable.Tpo $(DEPDIR)/ragel-cdtable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdtable.cpp' object='ragel-cdtable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdtable.o `test -f 'cdtable.cpp' || echo '$(srcdir)/'`cdtable.cpp ragel-cdtable.obj: cdtable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdtable.obj -MD -MP -MF $(DEPDIR)/ragel-cdtable.Tpo -c -o ragel-cdtable.obj `if test -f 'cdtable.cpp'; then $(CYGPATH_W) 'cdtable.cpp'; else $(CYGPATH_W) '$(srcdir)/cdtable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdtable.Tpo $(DEPDIR)/ragel-cdtable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdtable.cpp' object='ragel-cdtable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdtable.obj `if test -f 'cdtable.cpp'; then $(CYGPATH_W) 'cdtable.cpp'; else $(CYGPATH_W) '$(srcdir)/cdtable.cpp'; fi` ragel-cdftable.o: cdftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdftable.o -MD -MP -MF $(DEPDIR)/ragel-cdftable.Tpo -c -o ragel-cdftable.o `test -f 'cdftable.cpp' || echo '$(srcdir)/'`cdftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdftable.Tpo $(DEPDIR)/ragel-cdftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdftable.cpp' object='ragel-cdftable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdftable.o `test -f 'cdftable.cpp' || echo '$(srcdir)/'`cdftable.cpp ragel-cdftable.obj: cdftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdftable.obj -MD -MP -MF $(DEPDIR)/ragel-cdftable.Tpo -c -o ragel-cdftable.obj `if test -f 'cdftable.cpp'; then $(CYGPATH_W) 'cdftable.cpp'; else $(CYGPATH_W) '$(srcdir)/cdftable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdftable.Tpo $(DEPDIR)/ragel-cdftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdftable.cpp' object='ragel-cdftable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdftable.obj `if test -f 'cdftable.cpp'; then $(CYGPATH_W) 'cdftable.cpp'; else $(CYGPATH_W) '$(srcdir)/cdftable.cpp'; fi` ragel-cdflat.o: cdflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdflat.o -MD -MP -MF $(DEPDIR)/ragel-cdflat.Tpo -c -o ragel-cdflat.o `test -f 'cdflat.cpp' || echo '$(srcdir)/'`cdflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdflat.Tpo $(DEPDIR)/ragel-cdflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdflat.cpp' object='ragel-cdflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdflat.o `test -f 'cdflat.cpp' || echo '$(srcdir)/'`cdflat.cpp ragel-cdflat.obj: cdflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdflat.obj -MD -MP -MF $(DEPDIR)/ragel-cdflat.Tpo -c -o ragel-cdflat.obj `if test -f 'cdflat.cpp'; then $(CYGPATH_W) 'cdflat.cpp'; else $(CYGPATH_W) '$(srcdir)/cdflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdflat.Tpo $(DEPDIR)/ragel-cdflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdflat.cpp' object='ragel-cdflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdflat.obj `if test -f 'cdflat.cpp'; then $(CYGPATH_W) 'cdflat.cpp'; else $(CYGPATH_W) '$(srcdir)/cdflat.cpp'; fi` ragel-cdfflat.o: cdfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdfflat.o -MD -MP -MF $(DEPDIR)/ragel-cdfflat.Tpo -c -o ragel-cdfflat.o `test -f 'cdfflat.cpp' || echo '$(srcdir)/'`cdfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdfflat.Tpo $(DEPDIR)/ragel-cdfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdfflat.cpp' object='ragel-cdfflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdfflat.o `test -f 'cdfflat.cpp' || echo '$(srcdir)/'`cdfflat.cpp ragel-cdfflat.obj: cdfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdfflat.obj -MD -MP -MF $(DEPDIR)/ragel-cdfflat.Tpo -c -o ragel-cdfflat.obj `if test -f 'cdfflat.cpp'; then $(CYGPATH_W) 'cdfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/cdfflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdfflat.Tpo $(DEPDIR)/ragel-cdfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdfflat.cpp' object='ragel-cdfflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdfflat.obj `if test -f 'cdfflat.cpp'; then $(CYGPATH_W) 'cdfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/cdfflat.cpp'; fi` ragel-cdgoto.o: cdgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdgoto.o -MD -MP -MF $(DEPDIR)/ragel-cdgoto.Tpo -c -o ragel-cdgoto.o `test -f 'cdgoto.cpp' || echo '$(srcdir)/'`cdgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdgoto.Tpo $(DEPDIR)/ragel-cdgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdgoto.cpp' object='ragel-cdgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdgoto.o `test -f 'cdgoto.cpp' || echo '$(srcdir)/'`cdgoto.cpp ragel-cdgoto.obj: cdgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdgoto.obj -MD -MP -MF $(DEPDIR)/ragel-cdgoto.Tpo -c -o ragel-cdgoto.obj `if test -f 'cdgoto.cpp'; then $(CYGPATH_W) 'cdgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/cdgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdgoto.Tpo $(DEPDIR)/ragel-cdgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdgoto.cpp' object='ragel-cdgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdgoto.obj `if test -f 'cdgoto.cpp'; then $(CYGPATH_W) 'cdgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/cdgoto.cpp'; fi` ragel-cdfgoto.o: cdfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdfgoto.o -MD -MP -MF $(DEPDIR)/ragel-cdfgoto.Tpo -c -o ragel-cdfgoto.o `test -f 'cdfgoto.cpp' || echo '$(srcdir)/'`cdfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdfgoto.Tpo $(DEPDIR)/ragel-cdfgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdfgoto.cpp' object='ragel-cdfgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdfgoto.o `test -f 'cdfgoto.cpp' || echo '$(srcdir)/'`cdfgoto.cpp ragel-cdfgoto.obj: cdfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdfgoto.obj -MD -MP -MF $(DEPDIR)/ragel-cdfgoto.Tpo -c -o ragel-cdfgoto.obj `if test -f 'cdfgoto.cpp'; then $(CYGPATH_W) 'cdfgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/cdfgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdfgoto.Tpo $(DEPDIR)/ragel-cdfgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdfgoto.cpp' object='ragel-cdfgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdfgoto.obj `if test -f 'cdfgoto.cpp'; then $(CYGPATH_W) 'cdfgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/cdfgoto.cpp'; fi` ragel-cdipgoto.o: cdipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdipgoto.o -MD -MP -MF $(DEPDIR)/ragel-cdipgoto.Tpo -c -o ragel-cdipgoto.o `test -f 'cdipgoto.cpp' || echo '$(srcdir)/'`cdipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdipgoto.Tpo $(DEPDIR)/ragel-cdipgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdipgoto.cpp' object='ragel-cdipgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdipgoto.o `test -f 'cdipgoto.cpp' || echo '$(srcdir)/'`cdipgoto.cpp ragel-cdipgoto.obj: cdipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdipgoto.obj -MD -MP -MF $(DEPDIR)/ragel-cdipgoto.Tpo -c -o ragel-cdipgoto.obj `if test -f 'cdipgoto.cpp'; then $(CYGPATH_W) 'cdipgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/cdipgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdipgoto.Tpo $(DEPDIR)/ragel-cdipgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdipgoto.cpp' object='ragel-cdipgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdipgoto.obj `if test -f 'cdipgoto.cpp'; then $(CYGPATH_W) 'cdipgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/cdipgoto.cpp'; fi` ragel-cdsplit.o: cdsplit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdsplit.o -MD -MP -MF $(DEPDIR)/ragel-cdsplit.Tpo -c -o ragel-cdsplit.o `test -f 'cdsplit.cpp' || echo '$(srcdir)/'`cdsplit.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdsplit.Tpo $(DEPDIR)/ragel-cdsplit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdsplit.cpp' object='ragel-cdsplit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdsplit.o `test -f 'cdsplit.cpp' || echo '$(srcdir)/'`cdsplit.cpp ragel-cdsplit.obj: cdsplit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cdsplit.obj -MD -MP -MF $(DEPDIR)/ragel-cdsplit.Tpo -c -o ragel-cdsplit.obj `if test -f 'cdsplit.cpp'; then $(CYGPATH_W) 'cdsplit.cpp'; else $(CYGPATH_W) '$(srcdir)/cdsplit.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cdsplit.Tpo $(DEPDIR)/ragel-cdsplit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdsplit.cpp' object='ragel-cdsplit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cdsplit.obj `if test -f 'cdsplit.cpp'; then $(CYGPATH_W) 'cdsplit.cpp'; else $(CYGPATH_W) '$(srcdir)/cdsplit.cpp'; fi` ragel-javacodegen.o: javacodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-javacodegen.o -MD -MP -MF $(DEPDIR)/ragel-javacodegen.Tpo -c -o ragel-javacodegen.o `test -f 'javacodegen.cpp' || echo '$(srcdir)/'`javacodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-javacodegen.Tpo $(DEPDIR)/ragel-javacodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='javacodegen.cpp' object='ragel-javacodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-javacodegen.o `test -f 'javacodegen.cpp' || echo '$(srcdir)/'`javacodegen.cpp ragel-javacodegen.obj: javacodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-javacodegen.obj -MD -MP -MF $(DEPDIR)/ragel-javacodegen.Tpo -c -o ragel-javacodegen.obj `if test -f 'javacodegen.cpp'; then $(CYGPATH_W) 'javacodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/javacodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-javacodegen.Tpo $(DEPDIR)/ragel-javacodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='javacodegen.cpp' object='ragel-javacodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-javacodegen.obj `if test -f 'javacodegen.cpp'; then $(CYGPATH_W) 'javacodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/javacodegen.cpp'; fi` ragel-rubycodegen.o: rubycodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubycodegen.o -MD -MP -MF $(DEPDIR)/ragel-rubycodegen.Tpo -c -o ragel-rubycodegen.o `test -f 'rubycodegen.cpp' || echo '$(srcdir)/'`rubycodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubycodegen.Tpo $(DEPDIR)/ragel-rubycodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubycodegen.cpp' object='ragel-rubycodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubycodegen.o `test -f 'rubycodegen.cpp' || echo '$(srcdir)/'`rubycodegen.cpp ragel-rubycodegen.obj: rubycodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubycodegen.obj -MD -MP -MF $(DEPDIR)/ragel-rubycodegen.Tpo -c -o ragel-rubycodegen.obj `if test -f 'rubycodegen.cpp'; then $(CYGPATH_W) 'rubycodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/rubycodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubycodegen.Tpo $(DEPDIR)/ragel-rubycodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubycodegen.cpp' object='ragel-rubycodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubycodegen.obj `if test -f 'rubycodegen.cpp'; then $(CYGPATH_W) 'rubycodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/rubycodegen.cpp'; fi` ragel-rubytable.o: rubytable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubytable.o -MD -MP -MF $(DEPDIR)/ragel-rubytable.Tpo -c -o ragel-rubytable.o `test -f 'rubytable.cpp' || echo '$(srcdir)/'`rubytable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubytable.Tpo $(DEPDIR)/ragel-rubytable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubytable.cpp' object='ragel-rubytable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubytable.o `test -f 'rubytable.cpp' || echo '$(srcdir)/'`rubytable.cpp ragel-rubytable.obj: rubytable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubytable.obj -MD -MP -MF $(DEPDIR)/ragel-rubytable.Tpo -c -o ragel-rubytable.obj `if test -f 'rubytable.cpp'; then $(CYGPATH_W) 'rubytable.cpp'; else $(CYGPATH_W) '$(srcdir)/rubytable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubytable.Tpo $(DEPDIR)/ragel-rubytable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubytable.cpp' object='ragel-rubytable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubytable.obj `if test -f 'rubytable.cpp'; then $(CYGPATH_W) 'rubytable.cpp'; else $(CYGPATH_W) '$(srcdir)/rubytable.cpp'; fi` ragel-rubyftable.o: rubyftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubyftable.o -MD -MP -MF $(DEPDIR)/ragel-rubyftable.Tpo -c -o ragel-rubyftable.o `test -f 'rubyftable.cpp' || echo '$(srcdir)/'`rubyftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubyftable.Tpo $(DEPDIR)/ragel-rubyftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubyftable.cpp' object='ragel-rubyftable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubyftable.o `test -f 'rubyftable.cpp' || echo '$(srcdir)/'`rubyftable.cpp ragel-rubyftable.obj: rubyftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubyftable.obj -MD -MP -MF $(DEPDIR)/ragel-rubyftable.Tpo -c -o ragel-rubyftable.obj `if test -f 'rubyftable.cpp'; then $(CYGPATH_W) 'rubyftable.cpp'; else $(CYGPATH_W) '$(srcdir)/rubyftable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubyftable.Tpo $(DEPDIR)/ragel-rubyftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubyftable.cpp' object='ragel-rubyftable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubyftable.obj `if test -f 'rubyftable.cpp'; then $(CYGPATH_W) 'rubyftable.cpp'; else $(CYGPATH_W) '$(srcdir)/rubyftable.cpp'; fi` ragel-rubyflat.o: rubyflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubyflat.o -MD -MP -MF $(DEPDIR)/ragel-rubyflat.Tpo -c -o ragel-rubyflat.o `test -f 'rubyflat.cpp' || echo '$(srcdir)/'`rubyflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubyflat.Tpo $(DEPDIR)/ragel-rubyflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubyflat.cpp' object='ragel-rubyflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubyflat.o `test -f 'rubyflat.cpp' || echo '$(srcdir)/'`rubyflat.cpp ragel-rubyflat.obj: rubyflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubyflat.obj -MD -MP -MF $(DEPDIR)/ragel-rubyflat.Tpo -c -o ragel-rubyflat.obj `if test -f 'rubyflat.cpp'; then $(CYGPATH_W) 'rubyflat.cpp'; else $(CYGPATH_W) '$(srcdir)/rubyflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubyflat.Tpo $(DEPDIR)/ragel-rubyflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubyflat.cpp' object='ragel-rubyflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubyflat.obj `if test -f 'rubyflat.cpp'; then $(CYGPATH_W) 'rubyflat.cpp'; else $(CYGPATH_W) '$(srcdir)/rubyflat.cpp'; fi` ragel-rubyfflat.o: rubyfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubyfflat.o -MD -MP -MF $(DEPDIR)/ragel-rubyfflat.Tpo -c -o ragel-rubyfflat.o `test -f 'rubyfflat.cpp' || echo '$(srcdir)/'`rubyfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubyfflat.Tpo $(DEPDIR)/ragel-rubyfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubyfflat.cpp' object='ragel-rubyfflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubyfflat.o `test -f 'rubyfflat.cpp' || echo '$(srcdir)/'`rubyfflat.cpp ragel-rubyfflat.obj: rubyfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rubyfflat.obj -MD -MP -MF $(DEPDIR)/ragel-rubyfflat.Tpo -c -o ragel-rubyfflat.obj `if test -f 'rubyfflat.cpp'; then $(CYGPATH_W) 'rubyfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/rubyfflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rubyfflat.Tpo $(DEPDIR)/ragel-rubyfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rubyfflat.cpp' object='ragel-rubyfflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rubyfflat.obj `if test -f 'rubyfflat.cpp'; then $(CYGPATH_W) 'rubyfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/rubyfflat.cpp'; fi` ragel-rbxgoto.o: rbxgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rbxgoto.o -MD -MP -MF $(DEPDIR)/ragel-rbxgoto.Tpo -c -o ragel-rbxgoto.o `test -f 'rbxgoto.cpp' || echo '$(srcdir)/'`rbxgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rbxgoto.Tpo $(DEPDIR)/ragel-rbxgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rbxgoto.cpp' object='ragel-rbxgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rbxgoto.o `test -f 'rbxgoto.cpp' || echo '$(srcdir)/'`rbxgoto.cpp ragel-rbxgoto.obj: rbxgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-rbxgoto.obj -MD -MP -MF $(DEPDIR)/ragel-rbxgoto.Tpo -c -o ragel-rbxgoto.obj `if test -f 'rbxgoto.cpp'; then $(CYGPATH_W) 'rbxgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/rbxgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-rbxgoto.Tpo $(DEPDIR)/ragel-rbxgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rbxgoto.cpp' object='ragel-rbxgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-rbxgoto.obj `if test -f 'rbxgoto.cpp'; then $(CYGPATH_W) 'rbxgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/rbxgoto.cpp'; fi` ragel-cscodegen.o: cscodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cscodegen.o -MD -MP -MF $(DEPDIR)/ragel-cscodegen.Tpo -c -o ragel-cscodegen.o `test -f 'cscodegen.cpp' || echo '$(srcdir)/'`cscodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cscodegen.Tpo $(DEPDIR)/ragel-cscodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cscodegen.cpp' object='ragel-cscodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cscodegen.o `test -f 'cscodegen.cpp' || echo '$(srcdir)/'`cscodegen.cpp ragel-cscodegen.obj: cscodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cscodegen.obj -MD -MP -MF $(DEPDIR)/ragel-cscodegen.Tpo -c -o ragel-cscodegen.obj `if test -f 'cscodegen.cpp'; then $(CYGPATH_W) 'cscodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/cscodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cscodegen.Tpo $(DEPDIR)/ragel-cscodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cscodegen.cpp' object='ragel-cscodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cscodegen.obj `if test -f 'cscodegen.cpp'; then $(CYGPATH_W) 'cscodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/cscodegen.cpp'; fi` ragel-cstable.o: cstable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cstable.o -MD -MP -MF $(DEPDIR)/ragel-cstable.Tpo -c -o ragel-cstable.o `test -f 'cstable.cpp' || echo '$(srcdir)/'`cstable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cstable.Tpo $(DEPDIR)/ragel-cstable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cstable.cpp' object='ragel-cstable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cstable.o `test -f 'cstable.cpp' || echo '$(srcdir)/'`cstable.cpp ragel-cstable.obj: cstable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cstable.obj -MD -MP -MF $(DEPDIR)/ragel-cstable.Tpo -c -o ragel-cstable.obj `if test -f 'cstable.cpp'; then $(CYGPATH_W) 'cstable.cpp'; else $(CYGPATH_W) '$(srcdir)/cstable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cstable.Tpo $(DEPDIR)/ragel-cstable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cstable.cpp' object='ragel-cstable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cstable.obj `if test -f 'cstable.cpp'; then $(CYGPATH_W) 'cstable.cpp'; else $(CYGPATH_W) '$(srcdir)/cstable.cpp'; fi` ragel-csftable.o: csftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csftable.o -MD -MP -MF $(DEPDIR)/ragel-csftable.Tpo -c -o ragel-csftable.o `test -f 'csftable.cpp' || echo '$(srcdir)/'`csftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csftable.Tpo $(DEPDIR)/ragel-csftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csftable.cpp' object='ragel-csftable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csftable.o `test -f 'csftable.cpp' || echo '$(srcdir)/'`csftable.cpp ragel-csftable.obj: csftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csftable.obj -MD -MP -MF $(DEPDIR)/ragel-csftable.Tpo -c -o ragel-csftable.obj `if test -f 'csftable.cpp'; then $(CYGPATH_W) 'csftable.cpp'; else $(CYGPATH_W) '$(srcdir)/csftable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csftable.Tpo $(DEPDIR)/ragel-csftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csftable.cpp' object='ragel-csftable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csftable.obj `if test -f 'csftable.cpp'; then $(CYGPATH_W) 'csftable.cpp'; else $(CYGPATH_W) '$(srcdir)/csftable.cpp'; fi` ragel-csflat.o: csflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csflat.o -MD -MP -MF $(DEPDIR)/ragel-csflat.Tpo -c -o ragel-csflat.o `test -f 'csflat.cpp' || echo '$(srcdir)/'`csflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csflat.Tpo $(DEPDIR)/ragel-csflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csflat.cpp' object='ragel-csflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csflat.o `test -f 'csflat.cpp' || echo '$(srcdir)/'`csflat.cpp ragel-csflat.obj: csflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csflat.obj -MD -MP -MF $(DEPDIR)/ragel-csflat.Tpo -c -o ragel-csflat.obj `if test -f 'csflat.cpp'; then $(CYGPATH_W) 'csflat.cpp'; else $(CYGPATH_W) '$(srcdir)/csflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csflat.Tpo $(DEPDIR)/ragel-csflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csflat.cpp' object='ragel-csflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csflat.obj `if test -f 'csflat.cpp'; then $(CYGPATH_W) 'csflat.cpp'; else $(CYGPATH_W) '$(srcdir)/csflat.cpp'; fi` ragel-csfflat.o: csfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csfflat.o -MD -MP -MF $(DEPDIR)/ragel-csfflat.Tpo -c -o ragel-csfflat.o `test -f 'csfflat.cpp' || echo '$(srcdir)/'`csfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csfflat.Tpo $(DEPDIR)/ragel-csfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csfflat.cpp' object='ragel-csfflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csfflat.o `test -f 'csfflat.cpp' || echo '$(srcdir)/'`csfflat.cpp ragel-csfflat.obj: csfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csfflat.obj -MD -MP -MF $(DEPDIR)/ragel-csfflat.Tpo -c -o ragel-csfflat.obj `if test -f 'csfflat.cpp'; then $(CYGPATH_W) 'csfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/csfflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csfflat.Tpo $(DEPDIR)/ragel-csfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csfflat.cpp' object='ragel-csfflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csfflat.obj `if test -f 'csfflat.cpp'; then $(CYGPATH_W) 'csfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/csfflat.cpp'; fi` ragel-csgoto.o: csgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csgoto.o -MD -MP -MF $(DEPDIR)/ragel-csgoto.Tpo -c -o ragel-csgoto.o `test -f 'csgoto.cpp' || echo '$(srcdir)/'`csgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csgoto.Tpo $(DEPDIR)/ragel-csgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csgoto.cpp' object='ragel-csgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csgoto.o `test -f 'csgoto.cpp' || echo '$(srcdir)/'`csgoto.cpp ragel-csgoto.obj: csgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csgoto.obj -MD -MP -MF $(DEPDIR)/ragel-csgoto.Tpo -c -o ragel-csgoto.obj `if test -f 'csgoto.cpp'; then $(CYGPATH_W) 'csgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/csgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csgoto.Tpo $(DEPDIR)/ragel-csgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csgoto.cpp' object='ragel-csgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csgoto.obj `if test -f 'csgoto.cpp'; then $(CYGPATH_W) 'csgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/csgoto.cpp'; fi` ragel-csfgoto.o: csfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csfgoto.o -MD -MP -MF $(DEPDIR)/ragel-csfgoto.Tpo -c -o ragel-csfgoto.o `test -f 'csfgoto.cpp' || echo '$(srcdir)/'`csfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csfgoto.Tpo $(DEPDIR)/ragel-csfgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csfgoto.cpp' object='ragel-csfgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csfgoto.o `test -f 'csfgoto.cpp' || echo '$(srcdir)/'`csfgoto.cpp ragel-csfgoto.obj: csfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csfgoto.obj -MD -MP -MF $(DEPDIR)/ragel-csfgoto.Tpo -c -o ragel-csfgoto.obj `if test -f 'csfgoto.cpp'; then $(CYGPATH_W) 'csfgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/csfgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csfgoto.Tpo $(DEPDIR)/ragel-csfgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csfgoto.cpp' object='ragel-csfgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csfgoto.obj `if test -f 'csfgoto.cpp'; then $(CYGPATH_W) 'csfgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/csfgoto.cpp'; fi` ragel-csipgoto.o: csipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csipgoto.o -MD -MP -MF $(DEPDIR)/ragel-csipgoto.Tpo -c -o ragel-csipgoto.o `test -f 'csipgoto.cpp' || echo '$(srcdir)/'`csipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csipgoto.Tpo $(DEPDIR)/ragel-csipgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csipgoto.cpp' object='ragel-csipgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csipgoto.o `test -f 'csipgoto.cpp' || echo '$(srcdir)/'`csipgoto.cpp ragel-csipgoto.obj: csipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-csipgoto.obj -MD -MP -MF $(DEPDIR)/ragel-csipgoto.Tpo -c -o ragel-csipgoto.obj `if test -f 'csipgoto.cpp'; then $(CYGPATH_W) 'csipgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/csipgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-csipgoto.Tpo $(DEPDIR)/ragel-csipgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='csipgoto.cpp' object='ragel-csipgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-csipgoto.obj `if test -f 'csipgoto.cpp'; then $(CYGPATH_W) 'csipgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/csipgoto.cpp'; fi` ragel-cssplit.o: cssplit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cssplit.o -MD -MP -MF $(DEPDIR)/ragel-cssplit.Tpo -c -o ragel-cssplit.o `test -f 'cssplit.cpp' || echo '$(srcdir)/'`cssplit.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cssplit.Tpo $(DEPDIR)/ragel-cssplit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cssplit.cpp' object='ragel-cssplit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cssplit.o `test -f 'cssplit.cpp' || echo '$(srcdir)/'`cssplit.cpp ragel-cssplit.obj: cssplit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-cssplit.obj -MD -MP -MF $(DEPDIR)/ragel-cssplit.Tpo -c -o ragel-cssplit.obj `if test -f 'cssplit.cpp'; then $(CYGPATH_W) 'cssplit.cpp'; else $(CYGPATH_W) '$(srcdir)/cssplit.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-cssplit.Tpo $(DEPDIR)/ragel-cssplit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cssplit.cpp' object='ragel-cssplit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-cssplit.obj `if test -f 'cssplit.cpp'; then $(CYGPATH_W) 'cssplit.cpp'; else $(CYGPATH_W) '$(srcdir)/cssplit.cpp'; fi` ragel-dotcodegen.o: dotcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-dotcodegen.o -MD -MP -MF $(DEPDIR)/ragel-dotcodegen.Tpo -c -o ragel-dotcodegen.o `test -f 'dotcodegen.cpp' || echo '$(srcdir)/'`dotcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-dotcodegen.Tpo $(DEPDIR)/ragel-dotcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dotcodegen.cpp' object='ragel-dotcodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-dotcodegen.o `test -f 'dotcodegen.cpp' || echo '$(srcdir)/'`dotcodegen.cpp ragel-dotcodegen.obj: dotcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-dotcodegen.obj -MD -MP -MF $(DEPDIR)/ragel-dotcodegen.Tpo -c -o ragel-dotcodegen.obj `if test -f 'dotcodegen.cpp'; then $(CYGPATH_W) 'dotcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/dotcodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-dotcodegen.Tpo $(DEPDIR)/ragel-dotcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dotcodegen.cpp' object='ragel-dotcodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-dotcodegen.obj `if test -f 'dotcodegen.cpp'; then $(CYGPATH_W) 'dotcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/dotcodegen.cpp'; fi` ragel-xmlcodegen.o: xmlcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-xmlcodegen.o -MD -MP -MF $(DEPDIR)/ragel-xmlcodegen.Tpo -c -o ragel-xmlcodegen.o `test -f 'xmlcodegen.cpp' || echo '$(srcdir)/'`xmlcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-xmlcodegen.Tpo $(DEPDIR)/ragel-xmlcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xmlcodegen.cpp' object='ragel-xmlcodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-xmlcodegen.o `test -f 'xmlcodegen.cpp' || echo '$(srcdir)/'`xmlcodegen.cpp ragel-xmlcodegen.obj: xmlcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-xmlcodegen.obj -MD -MP -MF $(DEPDIR)/ragel-xmlcodegen.Tpo -c -o ragel-xmlcodegen.obj `if test -f 'xmlcodegen.cpp'; then $(CYGPATH_W) 'xmlcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/xmlcodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-xmlcodegen.Tpo $(DEPDIR)/ragel-xmlcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xmlcodegen.cpp' object='ragel-xmlcodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-xmlcodegen.obj `if test -f 'xmlcodegen.cpp'; then $(CYGPATH_W) 'xmlcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/xmlcodegen.cpp'; fi` ragel-gocodegen.o: gocodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gocodegen.o -MD -MP -MF $(DEPDIR)/ragel-gocodegen.Tpo -c -o ragel-gocodegen.o `test -f 'gocodegen.cpp' || echo '$(srcdir)/'`gocodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gocodegen.Tpo $(DEPDIR)/ragel-gocodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gocodegen.cpp' object='ragel-gocodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gocodegen.o `test -f 'gocodegen.cpp' || echo '$(srcdir)/'`gocodegen.cpp ragel-gocodegen.obj: gocodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gocodegen.obj -MD -MP -MF $(DEPDIR)/ragel-gocodegen.Tpo -c -o ragel-gocodegen.obj `if test -f 'gocodegen.cpp'; then $(CYGPATH_W) 'gocodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/gocodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gocodegen.Tpo $(DEPDIR)/ragel-gocodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gocodegen.cpp' object='ragel-gocodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gocodegen.obj `if test -f 'gocodegen.cpp'; then $(CYGPATH_W) 'gocodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/gocodegen.cpp'; fi` ragel-gotable.o: gotable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gotable.o -MD -MP -MF $(DEPDIR)/ragel-gotable.Tpo -c -o ragel-gotable.o `test -f 'gotable.cpp' || echo '$(srcdir)/'`gotable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gotable.Tpo $(DEPDIR)/ragel-gotable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gotable.cpp' object='ragel-gotable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gotable.o `test -f 'gotable.cpp' || echo '$(srcdir)/'`gotable.cpp ragel-gotable.obj: gotable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gotable.obj -MD -MP -MF $(DEPDIR)/ragel-gotable.Tpo -c -o ragel-gotable.obj `if test -f 'gotable.cpp'; then $(CYGPATH_W) 'gotable.cpp'; else $(CYGPATH_W) '$(srcdir)/gotable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gotable.Tpo $(DEPDIR)/ragel-gotable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gotable.cpp' object='ragel-gotable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gotable.obj `if test -f 'gotable.cpp'; then $(CYGPATH_W) 'gotable.cpp'; else $(CYGPATH_W) '$(srcdir)/gotable.cpp'; fi` ragel-goftable.o: goftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-goftable.o -MD -MP -MF $(DEPDIR)/ragel-goftable.Tpo -c -o ragel-goftable.o `test -f 'goftable.cpp' || echo '$(srcdir)/'`goftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-goftable.Tpo $(DEPDIR)/ragel-goftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='goftable.cpp' object='ragel-goftable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-goftable.o `test -f 'goftable.cpp' || echo '$(srcdir)/'`goftable.cpp ragel-goftable.obj: goftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-goftable.obj -MD -MP -MF $(DEPDIR)/ragel-goftable.Tpo -c -o ragel-goftable.obj `if test -f 'goftable.cpp'; then $(CYGPATH_W) 'goftable.cpp'; else $(CYGPATH_W) '$(srcdir)/goftable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-goftable.Tpo $(DEPDIR)/ragel-goftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='goftable.cpp' object='ragel-goftable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-goftable.obj `if test -f 'goftable.cpp'; then $(CYGPATH_W) 'goftable.cpp'; else $(CYGPATH_W) '$(srcdir)/goftable.cpp'; fi` ragel-goflat.o: goflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-goflat.o -MD -MP -MF $(DEPDIR)/ragel-goflat.Tpo -c -o ragel-goflat.o `test -f 'goflat.cpp' || echo '$(srcdir)/'`goflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-goflat.Tpo $(DEPDIR)/ragel-goflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='goflat.cpp' object='ragel-goflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-goflat.o `test -f 'goflat.cpp' || echo '$(srcdir)/'`goflat.cpp ragel-goflat.obj: goflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-goflat.obj -MD -MP -MF $(DEPDIR)/ragel-goflat.Tpo -c -o ragel-goflat.obj `if test -f 'goflat.cpp'; then $(CYGPATH_W) 'goflat.cpp'; else $(CYGPATH_W) '$(srcdir)/goflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-goflat.Tpo $(DEPDIR)/ragel-goflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='goflat.cpp' object='ragel-goflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-goflat.obj `if test -f 'goflat.cpp'; then $(CYGPATH_W) 'goflat.cpp'; else $(CYGPATH_W) '$(srcdir)/goflat.cpp'; fi` ragel-gofflat.o: gofflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gofflat.o -MD -MP -MF $(DEPDIR)/ragel-gofflat.Tpo -c -o ragel-gofflat.o `test -f 'gofflat.cpp' || echo '$(srcdir)/'`gofflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gofflat.Tpo $(DEPDIR)/ragel-gofflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gofflat.cpp' object='ragel-gofflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gofflat.o `test -f 'gofflat.cpp' || echo '$(srcdir)/'`gofflat.cpp ragel-gofflat.obj: gofflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gofflat.obj -MD -MP -MF $(DEPDIR)/ragel-gofflat.Tpo -c -o ragel-gofflat.obj `if test -f 'gofflat.cpp'; then $(CYGPATH_W) 'gofflat.cpp'; else $(CYGPATH_W) '$(srcdir)/gofflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gofflat.Tpo $(DEPDIR)/ragel-gofflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gofflat.cpp' object='ragel-gofflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gofflat.obj `if test -f 'gofflat.cpp'; then $(CYGPATH_W) 'gofflat.cpp'; else $(CYGPATH_W) '$(srcdir)/gofflat.cpp'; fi` ragel-gogoto.o: gogoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gogoto.o -MD -MP -MF $(DEPDIR)/ragel-gogoto.Tpo -c -o ragel-gogoto.o `test -f 'gogoto.cpp' || echo '$(srcdir)/'`gogoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gogoto.Tpo $(DEPDIR)/ragel-gogoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gogoto.cpp' object='ragel-gogoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gogoto.o `test -f 'gogoto.cpp' || echo '$(srcdir)/'`gogoto.cpp ragel-gogoto.obj: gogoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gogoto.obj -MD -MP -MF $(DEPDIR)/ragel-gogoto.Tpo -c -o ragel-gogoto.obj `if test -f 'gogoto.cpp'; then $(CYGPATH_W) 'gogoto.cpp'; else $(CYGPATH_W) '$(srcdir)/gogoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gogoto.Tpo $(DEPDIR)/ragel-gogoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gogoto.cpp' object='ragel-gogoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gogoto.obj `if test -f 'gogoto.cpp'; then $(CYGPATH_W) 'gogoto.cpp'; else $(CYGPATH_W) '$(srcdir)/gogoto.cpp'; fi` ragel-gofgoto.o: gofgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gofgoto.o -MD -MP -MF $(DEPDIR)/ragel-gofgoto.Tpo -c -o ragel-gofgoto.o `test -f 'gofgoto.cpp' || echo '$(srcdir)/'`gofgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gofgoto.Tpo $(DEPDIR)/ragel-gofgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gofgoto.cpp' object='ragel-gofgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gofgoto.o `test -f 'gofgoto.cpp' || echo '$(srcdir)/'`gofgoto.cpp ragel-gofgoto.obj: gofgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gofgoto.obj -MD -MP -MF $(DEPDIR)/ragel-gofgoto.Tpo -c -o ragel-gofgoto.obj `if test -f 'gofgoto.cpp'; then $(CYGPATH_W) 'gofgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/gofgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gofgoto.Tpo $(DEPDIR)/ragel-gofgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gofgoto.cpp' object='ragel-gofgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gofgoto.obj `if test -f 'gofgoto.cpp'; then $(CYGPATH_W) 'gofgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/gofgoto.cpp'; fi` ragel-goipgoto.o: goipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-goipgoto.o -MD -MP -MF $(DEPDIR)/ragel-goipgoto.Tpo -c -o ragel-goipgoto.o `test -f 'goipgoto.cpp' || echo '$(srcdir)/'`goipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-goipgoto.Tpo $(DEPDIR)/ragel-goipgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='goipgoto.cpp' object='ragel-goipgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-goipgoto.o `test -f 'goipgoto.cpp' || echo '$(srcdir)/'`goipgoto.cpp ragel-goipgoto.obj: goipgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-goipgoto.obj -MD -MP -MF $(DEPDIR)/ragel-goipgoto.Tpo -c -o ragel-goipgoto.obj `if test -f 'goipgoto.cpp'; then $(CYGPATH_W) 'goipgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/goipgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-goipgoto.Tpo $(DEPDIR)/ragel-goipgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='goipgoto.cpp' object='ragel-goipgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-goipgoto.obj `if test -f 'goipgoto.cpp'; then $(CYGPATH_W) 'goipgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/goipgoto.cpp'; fi` ragel-gotablish.o: gotablish.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gotablish.o -MD -MP -MF $(DEPDIR)/ragel-gotablish.Tpo -c -o ragel-gotablish.o `test -f 'gotablish.cpp' || echo '$(srcdir)/'`gotablish.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gotablish.Tpo $(DEPDIR)/ragel-gotablish.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gotablish.cpp' object='ragel-gotablish.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gotablish.o `test -f 'gotablish.cpp' || echo '$(srcdir)/'`gotablish.cpp ragel-gotablish.obj: gotablish.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-gotablish.obj -MD -MP -MF $(DEPDIR)/ragel-gotablish.Tpo -c -o ragel-gotablish.obj `if test -f 'gotablish.cpp'; then $(CYGPATH_W) 'gotablish.cpp'; else $(CYGPATH_W) '$(srcdir)/gotablish.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-gotablish.Tpo $(DEPDIR)/ragel-gotablish.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gotablish.cpp' object='ragel-gotablish.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-gotablish.obj `if test -f 'gotablish.cpp'; then $(CYGPATH_W) 'gotablish.cpp'; else $(CYGPATH_W) '$(srcdir)/gotablish.cpp'; fi` ragel-mlcodegen.o: mlcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlcodegen.o -MD -MP -MF $(DEPDIR)/ragel-mlcodegen.Tpo -c -o ragel-mlcodegen.o `test -f 'mlcodegen.cpp' || echo '$(srcdir)/'`mlcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlcodegen.Tpo $(DEPDIR)/ragel-mlcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlcodegen.cpp' object='ragel-mlcodegen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlcodegen.o `test -f 'mlcodegen.cpp' || echo '$(srcdir)/'`mlcodegen.cpp ragel-mlcodegen.obj: mlcodegen.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlcodegen.obj -MD -MP -MF $(DEPDIR)/ragel-mlcodegen.Tpo -c -o ragel-mlcodegen.obj `if test -f 'mlcodegen.cpp'; then $(CYGPATH_W) 'mlcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/mlcodegen.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlcodegen.Tpo $(DEPDIR)/ragel-mlcodegen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlcodegen.cpp' object='ragel-mlcodegen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlcodegen.obj `if test -f 'mlcodegen.cpp'; then $(CYGPATH_W) 'mlcodegen.cpp'; else $(CYGPATH_W) '$(srcdir)/mlcodegen.cpp'; fi` ragel-mltable.o: mltable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mltable.o -MD -MP -MF $(DEPDIR)/ragel-mltable.Tpo -c -o ragel-mltable.o `test -f 'mltable.cpp' || echo '$(srcdir)/'`mltable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mltable.Tpo $(DEPDIR)/ragel-mltable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mltable.cpp' object='ragel-mltable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mltable.o `test -f 'mltable.cpp' || echo '$(srcdir)/'`mltable.cpp ragel-mltable.obj: mltable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mltable.obj -MD -MP -MF $(DEPDIR)/ragel-mltable.Tpo -c -o ragel-mltable.obj `if test -f 'mltable.cpp'; then $(CYGPATH_W) 'mltable.cpp'; else $(CYGPATH_W) '$(srcdir)/mltable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mltable.Tpo $(DEPDIR)/ragel-mltable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mltable.cpp' object='ragel-mltable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mltable.obj `if test -f 'mltable.cpp'; then $(CYGPATH_W) 'mltable.cpp'; else $(CYGPATH_W) '$(srcdir)/mltable.cpp'; fi` ragel-mlftable.o: mlftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlftable.o -MD -MP -MF $(DEPDIR)/ragel-mlftable.Tpo -c -o ragel-mlftable.o `test -f 'mlftable.cpp' || echo '$(srcdir)/'`mlftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlftable.Tpo $(DEPDIR)/ragel-mlftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlftable.cpp' object='ragel-mlftable.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlftable.o `test -f 'mlftable.cpp' || echo '$(srcdir)/'`mlftable.cpp ragel-mlftable.obj: mlftable.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlftable.obj -MD -MP -MF $(DEPDIR)/ragel-mlftable.Tpo -c -o ragel-mlftable.obj `if test -f 'mlftable.cpp'; then $(CYGPATH_W) 'mlftable.cpp'; else $(CYGPATH_W) '$(srcdir)/mlftable.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlftable.Tpo $(DEPDIR)/ragel-mlftable.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlftable.cpp' object='ragel-mlftable.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlftable.obj `if test -f 'mlftable.cpp'; then $(CYGPATH_W) 'mlftable.cpp'; else $(CYGPATH_W) '$(srcdir)/mlftable.cpp'; fi` ragel-mlflat.o: mlflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlflat.o -MD -MP -MF $(DEPDIR)/ragel-mlflat.Tpo -c -o ragel-mlflat.o `test -f 'mlflat.cpp' || echo '$(srcdir)/'`mlflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlflat.Tpo $(DEPDIR)/ragel-mlflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlflat.cpp' object='ragel-mlflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlflat.o `test -f 'mlflat.cpp' || echo '$(srcdir)/'`mlflat.cpp ragel-mlflat.obj: mlflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlflat.obj -MD -MP -MF $(DEPDIR)/ragel-mlflat.Tpo -c -o ragel-mlflat.obj `if test -f 'mlflat.cpp'; then $(CYGPATH_W) 'mlflat.cpp'; else $(CYGPATH_W) '$(srcdir)/mlflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlflat.Tpo $(DEPDIR)/ragel-mlflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlflat.cpp' object='ragel-mlflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlflat.obj `if test -f 'mlflat.cpp'; then $(CYGPATH_W) 'mlflat.cpp'; else $(CYGPATH_W) '$(srcdir)/mlflat.cpp'; fi` ragel-mlfflat.o: mlfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlfflat.o -MD -MP -MF $(DEPDIR)/ragel-mlfflat.Tpo -c -o ragel-mlfflat.o `test -f 'mlfflat.cpp' || echo '$(srcdir)/'`mlfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlfflat.Tpo $(DEPDIR)/ragel-mlfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlfflat.cpp' object='ragel-mlfflat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlfflat.o `test -f 'mlfflat.cpp' || echo '$(srcdir)/'`mlfflat.cpp ragel-mlfflat.obj: mlfflat.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlfflat.obj -MD -MP -MF $(DEPDIR)/ragel-mlfflat.Tpo -c -o ragel-mlfflat.obj `if test -f 'mlfflat.cpp'; then $(CYGPATH_W) 'mlfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/mlfflat.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlfflat.Tpo $(DEPDIR)/ragel-mlfflat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlfflat.cpp' object='ragel-mlfflat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlfflat.obj `if test -f 'mlfflat.cpp'; then $(CYGPATH_W) 'mlfflat.cpp'; else $(CYGPATH_W) '$(srcdir)/mlfflat.cpp'; fi` ragel-mlgoto.o: mlgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlgoto.o -MD -MP -MF $(DEPDIR)/ragel-mlgoto.Tpo -c -o ragel-mlgoto.o `test -f 'mlgoto.cpp' || echo '$(srcdir)/'`mlgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlgoto.Tpo $(DEPDIR)/ragel-mlgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlgoto.cpp' object='ragel-mlgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlgoto.o `test -f 'mlgoto.cpp' || echo '$(srcdir)/'`mlgoto.cpp ragel-mlgoto.obj: mlgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlgoto.obj -MD -MP -MF $(DEPDIR)/ragel-mlgoto.Tpo -c -o ragel-mlgoto.obj `if test -f 'mlgoto.cpp'; then $(CYGPATH_W) 'mlgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/mlgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlgoto.Tpo $(DEPDIR)/ragel-mlgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlgoto.cpp' object='ragel-mlgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlgoto.obj `if test -f 'mlgoto.cpp'; then $(CYGPATH_W) 'mlgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/mlgoto.cpp'; fi` ragel-mlfgoto.o: mlfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlfgoto.o -MD -MP -MF $(DEPDIR)/ragel-mlfgoto.Tpo -c -o ragel-mlfgoto.o `test -f 'mlfgoto.cpp' || echo '$(srcdir)/'`mlfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlfgoto.Tpo $(DEPDIR)/ragel-mlfgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlfgoto.cpp' object='ragel-mlfgoto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlfgoto.o `test -f 'mlfgoto.cpp' || echo '$(srcdir)/'`mlfgoto.cpp ragel-mlfgoto.obj: mlfgoto.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -MT ragel-mlfgoto.obj -MD -MP -MF $(DEPDIR)/ragel-mlfgoto.Tpo -c -o ragel-mlfgoto.obj `if test -f 'mlfgoto.cpp'; then $(CYGPATH_W) 'mlfgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/mlfgoto.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ragel-mlfgoto.Tpo $(DEPDIR)/ragel-mlfgoto.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mlfgoto.cpp' object='ragel-mlfgoto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ragel_CXXFLAGS) $(CXXFLAGS) -c -o ragel-mlfgoto.obj `if test -f 'mlfgoto.cpp'; then $(CYGPATH_W) 'mlfgoto.cpp'; else $(CYGPATH_W) '$(srcdir)/mlfgoto.cpp'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) config.h installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-hdr \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile version.h: Makefile echo '#define VERSION "$(PACKAGE_VERSION)"' > version.h echo '#define PUBDATE "$(PUBDATE)"' >> version.h @BUILD_PARSERS_TRUE@rlparse.h: rlparse.kh @BUILD_PARSERS_TRUE@ kelbt -o $@ $< @BUILD_PARSERS_TRUE@rlparse.cpp: rlparse.kl rlparse.kh @BUILD_PARSERS_TRUE@ kelbt -o $@ $< # This dependency comes from the import of the parser defines # into the scanner. @BUILD_PARSERS_TRUE@rlscan.cpp: rlparse.h @BUILD_PARSERS_TRUE@rlscan.cpp: rlscan.rl @BUILD_PARSERS_TRUE@ ragel -G2 -I$(builddir) -o $@ $< # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ragel-6.10/ragel/mlftable.cpp0000664000175000017500000002556313065111230013044 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "mlftable.h" #include "redfsm.h" #include "gendata.h" /* Determine if we should use indicies or not. */ void OCamlFTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActListId) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActListId) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &OCamlFTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &OCamlFTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &OCamlFTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &OCamlFTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &OCamlFTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &OCamlFTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFTabCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); out << "\t()\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &OCamlFTabCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\t()\n"; } } genLineDirective( out ); return out; } void OCamlFTabCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); out << "type " << TYPE_STATE() << " = { mutable keys : int; mutable trans : int; }" << TOP_SEP(); out << "exception Goto_match" << TOP_SEP(); out << "exception Goto_again" << TOP_SEP(); out << "exception Goto_eof_trans" << TOP_SEP(); } void OCamlFTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " begin\n"; // if ( redFsm->anyRegCurStateRef() ) // out << klenType ", _ps"; out << " let state = { keys = 0; trans = 0; } in\n" " let rec do_start () =\n"; // if ( redFsm->anyConditions() ) // out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " = " << PE() << " then\n" " do_test_eof ()\n" "\telse\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " = " << redFsm->errState->id << " then\n" " do_out ()\n" "\telse\n"; } out << "\tdo_resume ()\n"; out << "and do_resume () =\n"; if ( redFsm->anyFromStateActions() ) { out << " begin match " << AT( FSA(), vCS() ) << " with\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); out << "\tbegin try\n"; LOCATE_TRANS(); out << "\twith Goto_match -> () end;\n"; out << "\tdo_match ()\n"; out << "and do_match () =\n"; if ( useIndicies ) out << " state.trans <- " << CAST(transType) << AT( I(), "state.trans" ) << ";\n"; out << "\tdo_eof_trans ()\n"; // if ( redFsm->anyEofTrans() ) out << "and do_eof_trans () =\n"; if ( redFsm->anyRegCurStateRef() ) out << " let ps = " << vCS() << " in\n"; out << " " << vCS() << " <- " << AT( TT() ,"state.trans" ) << ";\n" "\n"; if ( redFsm->anyRegActions() ) { out << " begin try if " << AT( TA() , "state.trans" ) << " = 0 then\n" " raise Goto_again;\n" "\n" " match " << AT( TA(), "state.trans" ) << " with\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " with Goto_again -> () end;\n" "\n"; } out << "\tdo_again ()\n"; // if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || // redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "\tand do_again () =\n"; if ( redFsm->anyToStateActions() ) { out << " begin match " << AT( TSA(), vCS() ) << " with\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " match " << vCS() << " with\n" "\t| " << redFsm->errState->id << " -> do_out ()\n" "\t| _ ->\n"; } out << "\t" << P() << " <- " << P() << " + 1;\n"; if ( !noEnd ) { out << " if " << P() << " <> " << PE() << " then\n" " do_resume ()\n" "\telse do_test_eof ()\n"; } else { out << " do_resume ()\n"; } // if ( testEofUsed ) out << "and do_test_eof () =\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " = " << vEOF() << " then\n" " begin try\n"; if ( redFsm->anyEofTrans() ) { out << " if " << AT( ET(), vCS() ) << " > 0 then\n" " begin\n" " state.trans <- " << CAST(transType) << "(" << AT( ET(), vCS() ) << " - 1);\n" " raise Goto_eof_trans;\n" " end;\n"; } if ( redFsm->anyEofActions() ) { out << " begin match " << AT( EA(), vCS() ) << " with\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " end\n"; } out << " with Goto_again -> do_again ()\n" " | Goto_eof_trans -> do_eof_trans () end\n" "\n"; } else { out << "\t()\n"; } if ( outLabelUsed ) out << " and do_out () = ()\n"; out << "\tin do_start ()\n"; out << " end;\n"; } ragel-6.10/ragel/dotcodegen.h0000664000175000017500000000265713065111230013035 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GVDOTGEN_H #define _GVDOTGEN_H #include #include "gendata.h" class GraphvizDotGen : public CodeGenData { public: GraphvizDotGen( ostream &out ) : CodeGenData(out) { } /* Print an fsm to out stream. */ void writeTransList( RedStateAp *state ); void writeDotFile( ); virtual void finishRagelDef(); virtual bool writeStatement( InputLoc &, int, char ** ); private: /* Writing labels and actions. */ std::ostream &ONCHAR( Key lowKey, Key highKey ); std::ostream &TRANS_ACTION( RedStateAp *fromState, RedTransAp *trans ); std::ostream &ACTION( RedAction *action ); std::ostream &KEY( Key key ); }; #endif ragel-6.10/ragel/rlscan.rl0000664000175000017500000007424513065111230012374 00000000000000/* * Copyright 2006-2007 Adrian Thurston * Copyright 2011 Josef Goettgens */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "ragel.h" #include "rlscan.h" #include "inputdata.h" //#define LOG_TOKENS using std::ifstream; using std::istream; using std::ostream; using std::cout; using std::cerr; using std::endl; enum InlineBlockType { CurlyDelimited, SemiTerminated }; #ifdef _WIN32 #define PATH_SEP '\\' #else #define PATH_SEP '/' #endif /* * The Scanner for Importing */ %%{ machine inline_token_scan; alphtype int; access tok_; # Import scanner tokens. import "rlparse.h"; main := |* # Define of number. IMP_Define IMP_Word IMP_UInt => { int base = tok_ts - token_data; int nameOff = 1; int numOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_UInt, token_strings[base+numOff], token_lens[base+numOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }; # Assignment of number. IMP_Word '=' IMP_UInt => { int base = tok_ts - token_data; int nameOff = 0; int numOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_UInt, token_strings[base+numOff], token_lens[base+numOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }; # Define of literal. IMP_Define IMP_Word IMP_Literal => { int base = tok_ts - token_data; int nameOff = 1; int litOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_Literal, token_strings[base+litOff], token_lens[base+litOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }; # Assignment of literal. IMP_Word '=' IMP_Literal => { int base = tok_ts - token_data; int nameOff = 0; int litOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_Literal, token_strings[base+litOff], token_lens[base+litOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }; # Catch everything else. any; *|; }%% %% write data; void Scanner::flushImport() { int *p = token_data; int *pe = token_data + cur_token; int *eof = 0; %%{ machine inline_token_scan; write init; write exec; }%% if ( tok_ts == 0 ) cur_token = 0; else { cur_token = pe - tok_ts; int ts_offset = tok_ts - token_data; memmove( token_data, token_data+ts_offset, cur_token*sizeof(token_data[0]) ); memmove( token_strings, token_strings+ts_offset, cur_token*sizeof(token_strings[0]) ); memmove( token_lens, token_lens+ts_offset, cur_token*sizeof(token_lens[0]) ); } } void Scanner::directToParser( Parser *toParser, const char *tokFileName, int tokLine, int tokColumn, int type, char *tokdata, int toklen ) { InputLoc loc; #ifdef LOG_TOKENS cerr << "scanner:" << tokLine << ":" << tokColumn << ": sending token to the parser " << Parser_lelNames[type]; cerr << " " << toklen; if ( tokdata != 0 ) cerr << " " << tokdata; cerr << endl; #endif loc.fileName = tokFileName; loc.line = tokLine; loc.col = tokColumn; toParser->token( loc, type, tokdata, toklen ); } void Scanner::importToken( int token, char *start, char *end ) { if ( cur_token == max_tokens ) flushImport(); token_data[cur_token] = token; if ( start == 0 ) { token_strings[cur_token] = 0; token_lens[cur_token] = 0; } else { int toklen = end-start; token_lens[cur_token] = toklen; token_strings[cur_token] = new char[toklen+1]; memcpy( token_strings[cur_token], start, toklen ); token_strings[cur_token][toklen] = 0; } cur_token++; } void Scanner::pass( int token, char *start, char *end ) { if ( importMachines ) importToken( token, start, end ); pass(); } void Scanner::pass() { updateCol(); /* If no errors and we are at the bottom of the include stack (the * source file listed on the command line) then write out the data. */ if ( includeDepth == 0 && machineSpec == 0 && machineName == 0 ) id.inputItems.tail->data.write( ts, te-ts ); } /* * The scanner for processing sections, includes, imports, etc. */ %%{ machine section_parse; alphtype int; write data; }%% void Scanner::init( ) { %% write init; } bool Scanner::active() { if ( ignoreSection ) return false; if ( parser == 0 && ! parserExistsError ) { scan_error() << "this specification has no name, nor does any previous" " specification" << endl; parserExistsError = true; } if ( parser == 0 ) return false; return true; } ostream &Scanner::scan_error() { /* Maintain the error count. */ gblErrorCount += 1; cerr << makeInputLoc( fileName, line, column ) << ": "; return cerr; } /* An approximate check for duplicate includes. Due to aliasing of files it's * possible for duplicates to creep in. */ bool Scanner::duplicateInclude( char *inclFileName, char *inclSectionName ) { for ( IncludeHistory::Iter hi = parser->includeHistory; hi.lte(); hi++ ) { if ( strcmp( hi->fileName, inclFileName ) == 0 && strcmp( hi->sectionName, inclSectionName ) == 0 ) { return true; } } return false; } void Scanner::updateCol() { char *from = lastnl; if ( from == 0 ) from = ts; //cerr << "adding " << te - from << " to column" << endl; column += te - from; lastnl = 0; } void Scanner::handleMachine() { /* Assign a name to the machine. */ char *machine = word; if ( !importMachines && inclSectionTarg == 0 ) { ignoreSection = false; ParserDictEl *pdEl = id.parserDict.find( machine ); if ( pdEl == 0 ) { pdEl = new ParserDictEl( machine ); pdEl->value = new Parser( fileName, machine, sectionLoc ); pdEl->value->init(); id.parserDict.insert( pdEl ); id.parserList.append( pdEl->value ); } parser = pdEl->value; } else if ( !importMachines && strcmp( inclSectionTarg, machine ) == 0 ) { /* found include target */ ignoreSection = false; parser = inclToParser; } else { /* ignoring section */ ignoreSection = true; parser = 0; } } void Scanner::handleInclude() { if ( active() ) { char *inclSectionName = word; char **includeChecks = 0; /* Implement defaults for the input file and section name. */ if ( inclSectionName == 0 ) inclSectionName = parser->sectionName; if ( lit != 0 ) includeChecks = makeIncludePathChecks( fileName, lit, lit_len ); else { char *test = new char[strlen(fileName)+1]; strcpy( test, fileName ); includeChecks = new char*[2]; includeChecks[0] = test; includeChecks[1] = 0; } long found = 0; ifstream *inFile = tryOpenInclude( includeChecks, found ); if ( inFile == 0 ) { scan_error() << "include: failed to locate file" << endl; char **tried = includeChecks; while ( *tried != 0 ) scan_error() << "include: attempted: \"" << *tried++ << '\"' << endl; } else { /* Don't include anything that's already been included. */ if ( !duplicateInclude( includeChecks[found], inclSectionName ) ) { parser->includeHistory.append( IncludeHistoryItem( includeChecks[found], inclSectionName ) ); Scanner scanner( id, includeChecks[found], *inFile, parser, inclSectionName, includeDepth+1, false ); scanner.do_scan( ); delete inFile; } } } } void Scanner::handleImport() { if ( active() ) { char **importChecks = makeIncludePathChecks( fileName, lit, lit_len ); /* Open the input file for reading. */ long found = 0; ifstream *inFile = tryOpenInclude( importChecks, found ); if ( inFile == 0 ) { scan_error() << "import: could not open import file " << "for reading" << endl; char **tried = importChecks; while ( *tried != 0 ) scan_error() << "import: attempted: \"" << *tried++ << '\"' << endl; } Scanner scanner( id, importChecks[found], *inFile, parser, 0, includeDepth+1, true ); scanner.do_scan( ); scanner.importToken( 0, 0, 0 ); scanner.flushImport(); delete inFile; } } %%{ machine section_parse; # Need the defines representing tokens. import "rlparse.h"; action clear_words { word = lit = 0; word_len = lit_len = 0; } action store_word { word = tokdata; word_len = toklen; } action store_lit { lit = tokdata; lit_len = toklen; } action mach_err { scan_error() << "bad machine statement" << endl; } action incl_err { scan_error() << "bad include statement" << endl; } action import_err { scan_error() << "bad import statement" << endl; } action write_err { scan_error() << "bad write statement" << endl; } action handle_machine { handleMachine(); } action handle_include { handleInclude(); } action handle_import { handleImport(); } machine_stmt = ( KW_Machine TK_Word @store_word ';' ) @handle_machine <>err mach_err <>eof mach_err; include_names = ( TK_Word @store_word ( TK_Literal @store_lit )? | TK_Literal @store_lit ) >clear_words; include_stmt = ( KW_Include include_names ';' ) @handle_include <>err incl_err <>eof incl_err; import_stmt = ( KW_Import TK_Literal @store_lit ';' ) @handle_import <>err import_err <>eof import_err; action write_command { if ( active() && machineSpec == 0 && machineName == 0 ) { InputItem *inputItem = new InputItem; inputItem->type = InputItem::Write; inputItem->loc.fileName = fileName; inputItem->loc.line = line; inputItem->loc.col = column; inputItem->name = parser->sectionName; inputItem->pd = parser->pd; id.inputItems.append( inputItem ); } } action write_arg { if ( active() && machineSpec == 0 && machineName == 0 ) id.inputItems.tail->writeArgs.append( strdup(tokdata) ); } action write_close { if ( active() && machineSpec == 0 && machineName == 0 ) id.inputItems.tail->writeArgs.append( 0 ); } write_stmt = ( KW_Write @write_command ( TK_Word @write_arg )+ ';' @write_close ) <>err write_err <>eof write_err; action handle_token { /* Send the token off to the parser. */ if ( active() ) directToParser( parser, fileName, line, column, type, tokdata, toklen ); } # Catch everything else. everything_else = ^( KW_Machine | KW_Include | KW_Import | KW_Write ) @handle_token; main := ( machine_stmt | include_stmt | import_stmt | write_stmt | everything_else )*; }%% void Scanner::token( int type, char c ) { token( type, &c, &c + 1 ); } void Scanner::token( int type ) { token( type, 0, 0 ); } void Scanner::token( int type, char *start, char *end ) { char *tokdata = 0; int toklen = 0; if ( start != 0 ) { toklen = end-start; tokdata = new char[toklen+1]; memcpy( tokdata, start, toklen ); tokdata[toklen] = 0; } processToken( type, tokdata, toklen ); } void Scanner::processToken( int type, char *tokdata, int toklen ) { int *p, *pe, *eof; if ( type < 0 ) p = pe = eof = 0; else { p = &type; pe = &type + 1; eof = 0; } %%{ machine section_parse; write exec; }%% updateCol(); /* Record the last token for use in controlling the scan of subsequent * tokens. */ lastToken = type; } void Scanner::startSection( ) { parserExistsError = false; sectionLoc.fileName = fileName; sectionLoc.line = line; sectionLoc.col = column; } void Scanner::endSection( ) { /* Execute the eof actions for the section parser. */ processToken( -1, 0, 0 ); /* Close off the section with the parser. */ if ( active() ) { InputLoc loc; loc.fileName = fileName; loc.line = line; loc.col = column; parser->token( loc, TK_EndSection, 0, 0 ); } if ( includeDepth == 0 ) { if ( machineSpec == 0 && machineName == 0 ) { /* The end section may include a newline on the end, so * we use the last line, which will count the newline. */ InputItem *inputItem = new InputItem; inputItem->type = InputItem::HostData; inputItem->loc.line = line; inputItem->loc.col = column; id.inputItems.append( inputItem ); } } } bool isAbsolutePath( const char *path ) { #ifdef _WIN32 return isalpha( path[0] ) && path[1] == ':' && path[2] == '\\'; #else return path[0] == '/'; #endif } char **Scanner::makeIncludePathChecks( const char *thisFileName, const char *fileName, int fnlen ) { char **checks = 0; long nextCheck = 0; long length = 0; bool caseInsensitive = false; char *data = prepareLitString( InputLoc(), fileName, fnlen, length, caseInsensitive ); /* Absolute path? */ if ( isAbsolutePath( data ) ) { checks = new char*[2]; checks[nextCheck++] = data; } else { checks = new char*[2 + id.includePaths.length()]; /* Search from the the location of the current file. */ const char *lastSlash = strrchr( thisFileName, PATH_SEP ); if ( lastSlash == 0 ) checks[nextCheck++] = data; else { long givenPathLen = (lastSlash - thisFileName) + 1; long checklen = givenPathLen + length; char *check = new char[checklen+1]; memcpy( check, thisFileName, givenPathLen ); memcpy( check+givenPathLen, data, length ); check[checklen] = 0; checks[nextCheck++] = check; } /* Search from the include paths given on the command line. */ for ( ArgsVector::Iter incp = id.includePaths; incp.lte(); incp++ ) { long pathLen = strlen( *incp ); long checkLen = pathLen + 1 + length; char *check = new char[checkLen+1]; memcpy( check, *incp, pathLen ); check[pathLen] = PATH_SEP; memcpy( check+pathLen+1, data, length ); check[checkLen] = 0; checks[nextCheck++] = check; } } checks[nextCheck] = 0; return checks; } ifstream *Scanner::tryOpenInclude( char **pathChecks, long &found ) { char **check = pathChecks; ifstream *inFile = new ifstream; while ( *check != 0 ) { inFile->open( *check ); if ( inFile->is_open() ) { found = check - pathChecks; return inFile; } /* * 03/26/2011 jg: * Don't rely on sloppy runtime behaviour: reset the state of the stream explicitly. * If inFile->open() fails, which happens when include dirs are tested, the fail bit * is set by the runtime library. Currently the VS runtime library opens new files, * but when it comes to reading it refuses to work. */ inFile->clear(); check += 1; } found = -1; delete inFile; return 0; } %%{ machine rlscan; # This is sent by the driver code. EOF = 0; action inc_nl { lastnl = p; column = 0; line++; } NL = '\n' @inc_nl; # Identifiers, numbers, commetns, and other common things. ident = ( alpha | '_' ) ( alpha |digit |'_' )*; number = digit+; hex_number = '0x' [0-9a-fA-F]+; c_comment = '/*' ( any | NL )* :>> '*/'; cpp_comment = '//' [^\n]* NL; c_cpp_comment = c_comment | cpp_comment; ruby_comment = '#' [^\n]* NL; # These literal forms are common to host code and ragel. s_literal = "'" ([^'\\] | NL | '\\' (any | NL))* "'"; d_literal = '"' ([^"\\] | NL | '\\' (any | NL))* '"'; host_re_literal = '/' ([^/\\] | NL | '\\' (any | NL))* '/'; whitespace = [ \t] | NL; pound_comment = '#' [^\n]* NL; # An inline block of code for Ruby. inline_code_ruby := |* # Inline expression keywords. "fpc" => { token( KW_PChar ); }; "fc" => { token( KW_Char ); }; "fcurs" => { token( KW_CurState ); }; "ftargs" => { token( KW_TargState ); }; "fentry" => { whitespaceOn = false; token( KW_Entry ); }; # Inline statement keywords. "fhold" => { whitespaceOn = false; token( KW_Hold ); }; "fexec" => { token( KW_Exec, 0, 0 ); }; "fgoto" => { whitespaceOn = false; token( KW_Goto ); }; "fnext" => { whitespaceOn = false; token( KW_Next ); }; "fcall" => { whitespaceOn = false; token( KW_Call ); }; "fret" => { whitespaceOn = false; token( KW_Ret ); }; "fbreak" => { whitespaceOn = false; token( KW_Break ); }; ident => { token( TK_Word, ts, te ); }; number => { token( TK_UInt, ts, te ); }; hex_number => { token( TK_Hex, ts, te ); }; ( s_literal | d_literal | host_re_literal ) => { token( IL_Literal, ts, te ); }; whitespace+ => { if ( whitespaceOn ) token( IL_WhiteSpace, ts, te ); }; ruby_comment => { token( IL_Comment, ts, te ); }; "::" => { token( TK_NameSep, ts, te ); }; # Some symbols need to go to the parser as with their cardinal value as # the token type (as opposed to being sent as anonymous symbols) # because they are part of the sequences which we interpret. The * ) ; # symbols cause whitespace parsing to come back on. This gets turned # off by some keywords. ";" => { whitespaceOn = true; token( *ts, ts, te ); if ( inlineBlockType == SemiTerminated ) fret; }; [*)] => { whitespaceOn = true; token( *ts, ts, te ); }; [,(] => { token( *ts, ts, te ); }; '{' => { token( IL_Symbol, ts, te ); curly_count += 1; }; '}' => { if ( --curly_count == 0 && inlineBlockType == CurlyDelimited ) { /* Inline code block ends. */ token( '}' ); fret; } else { /* Either a semi terminated inline block or only the closing * brace of some inner scope, not the block's closing brace. */ token( IL_Symbol, ts, te ); } }; EOF => { scan_error() << "unterminated code block" << endl; }; # Send every other character as a symbol. any => { token( IL_Symbol, ts, te ); }; *|; # An inline block of code for languages other than Ruby. inline_code := |* # Inline expression keywords. "fpc" => { token( KW_PChar ); }; "fc" => { token( KW_Char ); }; "fcurs" => { token( KW_CurState ); }; "ftargs" => { token( KW_TargState ); }; "fentry" => { whitespaceOn = false; token( KW_Entry ); }; # Inline statement keywords. "fhold" => { whitespaceOn = false; token( KW_Hold ); }; "fexec" => { token( KW_Exec, 0, 0 ); }; "fgoto" => { whitespaceOn = false; token( KW_Goto ); }; "fnext" => { whitespaceOn = false; token( KW_Next ); }; "fcall" => { whitespaceOn = false; token( KW_Call ); }; "fret" => { whitespaceOn = false; token( KW_Ret ); }; "fbreak" => { whitespaceOn = false; token( KW_Break ); }; ident => { token( TK_Word, ts, te ); }; number => { token( TK_UInt, ts, te ); }; hex_number => { token( TK_Hex, ts, te ); }; ( s_literal | d_literal ) => { token( IL_Literal, ts, te ); }; whitespace+ => { if ( whitespaceOn ) token( IL_WhiteSpace, ts, te ); }; c_cpp_comment => { token( IL_Comment, ts, te ); }; "::" => { token( TK_NameSep, ts, te ); }; # Some symbols need to go to the parser as with their cardinal value as # the token type (as opposed to being sent as anonymous symbols) # because they are part of the sequences which we interpret. The * ) ; # symbols cause whitespace parsing to come back on. This gets turned # off by some keywords. ";" => { whitespaceOn = true; token( *ts, ts, te ); if ( inlineBlockType == SemiTerminated ) fret; }; [*)] => { whitespaceOn = true; token( *ts, ts, te ); }; [,(] => { token( *ts, ts, te ); }; '{' => { token( IL_Symbol, ts, te ); curly_count += 1; }; '}' => { if ( --curly_count == 0 && inlineBlockType == CurlyDelimited ) { /* Inline code block ends. */ token( '}' ); fret; } else { /* Either a semi terminated inline block or only the closing * brace of some inner scope, not the block's closing brace. */ token( IL_Symbol, ts, te ); } }; EOF => { scan_error() << "unterminated code block" << endl; }; # Send every other character as a symbol. any => { token( IL_Symbol, ts, te ); }; *|; or_literal := |* # Escape sequences in OR expressions. '\\0' => { token( RE_Char, '\0' ); }; '\\a' => { token( RE_Char, '\a' ); }; '\\b' => { token( RE_Char, '\b' ); }; '\\t' => { token( RE_Char, '\t' ); }; '\\n' => { token( RE_Char, '\n' ); }; '\\v' => { token( RE_Char, '\v' ); }; '\\f' => { token( RE_Char, '\f' ); }; '\\r' => { token( RE_Char, '\r' ); }; '\\\n' => { updateCol(); }; '\\' any => { token( RE_Char, ts+1, te ); }; # Range dash in an OR expression. '-' => { token( RE_Dash, 0, 0 ); }; # Terminate an OR expression. ']' => { token( RE_SqClose ); fret; }; EOF => { scan_error() << "unterminated OR literal" << endl; }; # Characters in an OR expression. [^\]] => { token( RE_Char, ts, te ); }; *|; ragel_re_literal := |* # Escape sequences in regular expressions. '\\0' => { token( RE_Char, '\0' ); }; '\\a' => { token( RE_Char, '\a' ); }; '\\b' => { token( RE_Char, '\b' ); }; '\\t' => { token( RE_Char, '\t' ); }; '\\n' => { token( RE_Char, '\n' ); }; '\\v' => { token( RE_Char, '\v' ); }; '\\f' => { token( RE_Char, '\f' ); }; '\\r' => { token( RE_Char, '\r' ); }; '\\\n' => { updateCol(); }; '\\' any => { token( RE_Char, ts+1, te ); }; # Terminate an OR expression. '/' [i]? => { token( RE_Slash, ts, te ); fgoto parser_def; }; # Special characters. '.' => { token( RE_Dot ); }; '*' => { token( RE_Star ); }; '[' => { token( RE_SqOpen ); fcall or_literal; }; '[^' => { token( RE_SqOpenNeg ); fcall or_literal; }; EOF => { scan_error() << "unterminated regular expression" << endl; }; # Characters in an OR expression. [^\/] => { token( RE_Char, ts, te ); }; *|; # We need a separate token space here to avoid the ragel keywords. write_statement := |* ident => { token( TK_Word, ts, te ); } ; [ \t\n]+ => { updateCol(); }; ';' => { token( ';' ); fgoto parser_def; }; EOF => { scan_error() << "unterminated write statement" << endl; }; *|; # Parser definitions. parser_def := |* #'length_cond' => { token( KW_Length ); }; 'machine' => { token( KW_Machine ); }; 'include' => { token( KW_Include ); }; 'import' => { token( KW_Import ); }; 'write' => { token( KW_Write ); fgoto write_statement; }; 'action' => { token( KW_Action ); }; 'alphtype' => { token( KW_AlphType ); }; 'prepush' => { token( KW_PrePush ); }; 'postpop' => { token( KW_PostPop ); }; # FIXME: Enable this post 5.17. # 'range' => { token( KW_Range ); }; 'getkey' => { token( KW_GetKey ); inlineBlockType = SemiTerminated; if ( hostLang->lang == HostLang::Ruby ) fcall inline_code_ruby; else fcall inline_code; }; 'access' => { token( KW_Access ); inlineBlockType = SemiTerminated; if ( hostLang->lang == HostLang::Ruby ) fcall inline_code_ruby; else fcall inline_code; }; 'variable' => { token( KW_Variable ); inlineBlockType = SemiTerminated; if ( hostLang->lang == HostLang::Ruby ) fcall inline_code_ruby; else fcall inline_code; }; 'when' => { token( KW_When ); }; 'inwhen' => { token( KW_InWhen ); }; 'outwhen' => { token( KW_OutWhen ); }; 'eof' => { token( KW_Eof ); }; 'err' => { token( KW_Err ); }; 'lerr' => { token( KW_Lerr ); }; 'to' => { token( KW_To ); }; 'from' => { token( KW_From ); }; 'export' => { token( KW_Export ); }; # Identifiers. ident => { token( TK_Word, ts, te ); } ; # Numbers number => { token( TK_UInt, ts, te ); }; hex_number => { token( TK_Hex, ts, te ); }; # Literals, with optionals. ( s_literal | d_literal ) [i]? => { token( TK_Literal, ts, te ); }; '[' => { token( RE_SqOpen ); fcall or_literal; }; '[^' => { token( RE_SqOpenNeg ); fcall or_literal; }; '/' => { token( RE_Slash ); fgoto ragel_re_literal; }; # Ignore. pound_comment => { updateCol(); }; ':=' => { token( TK_ColonEquals ); }; # To State Actions. ">~" => { token( TK_StartToState ); }; "$~" => { token( TK_AllToState ); }; "%~" => { token( TK_FinalToState ); }; "<~" => { token( TK_NotStartToState ); }; "@~" => { token( TK_NotFinalToState ); }; "<>~" => { token( TK_MiddleToState ); }; # From State actions ">*" => { token( TK_StartFromState ); }; "$*" => { token( TK_AllFromState ); }; "%*" => { token( TK_FinalFromState ); }; "<*" => { token( TK_NotStartFromState ); }; "@*" => { token( TK_NotFinalFromState ); }; "<>*" => { token( TK_MiddleFromState ); }; # EOF Actions. ">/" => { token( TK_StartEOF ); }; "$/" => { token( TK_AllEOF ); }; "%/" => { token( TK_FinalEOF ); }; " { token( TK_NotStartEOF ); }; "@/" => { token( TK_NotFinalEOF ); }; "<>/" => { token( TK_MiddleEOF ); }; # Global Error actions. ">!" => { token( TK_StartGblError ); }; "$!" => { token( TK_AllGblError ); }; "%!" => { token( TK_FinalGblError ); }; " { token( TK_NotStartGblError ); }; "@!" => { token( TK_NotFinalGblError ); }; "<>!" => { token( TK_MiddleGblError ); }; # Local error actions. ">^" => { token( TK_StartLocalError ); }; "$^" => { token( TK_AllLocalError ); }; "%^" => { token( TK_FinalLocalError ); }; "<^" => { token( TK_NotStartLocalError ); }; "@^" => { token( TK_NotFinalLocalError ); }; "<>^" => { token( TK_MiddleLocalError ); }; # Middle. "<>" => { token( TK_Middle ); }; # Conditions. '>?' => { token( TK_StartCond ); }; '$?' => { token( TK_AllCond ); }; '%?' => { token( TK_LeavingCond ); }; '..' => { token( TK_DotDot ); }; '**' => { token( TK_StarStar ); }; '--' => { token( TK_DashDash ); }; '->' => { token( TK_Arrow ); }; '=>' => { token( TK_DoubleArrow ); }; ":>" => { token( TK_ColonGt ); }; ":>>" => { token( TK_ColonGtGt ); }; "<:" => { token( TK_LtColon ); }; # Opening of longest match. "|*" => { token( TK_BarStar ); }; # Separater for name references. "::" => { token( TK_NameSep, ts, te ); }; '}%%' => { updateCol(); endSection(); fret; }; [ \t\r]+ => { updateCol(); }; # If we are in a single line machine then newline may end the spec. NL => { updateCol(); if ( singleLineSpec ) { endSection(); fret; } }; '{' => { if ( lastToken == KW_Export || lastToken == KW_Entry ) token( '{' ); else { token( '{' ); curly_count = 1; inlineBlockType = CurlyDelimited; if ( hostLang->lang == HostLang::Ruby ) fcall inline_code_ruby; else fcall inline_code; } }; EOF => { scan_error() << "unterminated ragel section" << endl; }; any => { token( *ts ); } ; *|; # Outside code scanner. These tokens get passed through. main_ruby := |* ident => { pass( IMP_Word, ts, te ); }; number => { pass( IMP_UInt, ts, te ); }; ruby_comment => { pass(); }; ( s_literal | d_literal | host_re_literal ) => { pass( IMP_Literal, ts, te ); }; '%%{' => { updateCol(); singleLineSpec = false; startSection(); fcall parser_def; }; '%%' => { updateCol(); singleLineSpec = true; startSection(); fcall parser_def; }; whitespace+ => { pass(); }; EOF; any => { pass( *ts, 0, 0 ); }; *|; # Outside code scanner. These tokens get passed through. main := |* 'define' => { pass( IMP_Define, 0, 0 ); }; ident => { pass( IMP_Word, ts, te ); }; number => { pass( IMP_UInt, ts, te ); }; c_cpp_comment => { pass(); }; ( s_literal | d_literal ) => { pass( IMP_Literal, ts, te ); }; '%%{' => { updateCol(); singleLineSpec = false; startSection(); fcall parser_def; }; '%%' => { updateCol(); singleLineSpec = true; startSection(); fcall parser_def; }; whitespace+ => { pass(); }; EOF; any => { pass( *ts, 0, 0 ); }; *|; }%% %% write data; void Scanner::do_scan() { int bufsize = 8; char *buf = new char[bufsize]; int cs, act, have = 0; int top; /* The stack is two deep, one level for going into ragel defs from the main * machines which process outside code, and another for going into or literals * from either a ragel spec, or a regular expression. */ int stack[2]; int curly_count = 0; bool execute = true; bool singleLineSpec = false; InlineBlockType inlineBlockType = CurlyDelimited; /* Init the section parser and the character scanner. */ init(); %% write init; /* Set up the start state. FIXME: After 5.20 is released the nocs write * init option should be used, the main machine eliminated and this statement moved * above the write init. */ if ( hostLang->lang == HostLang::Ruby ) cs = rlscan_en_main_ruby; else cs = rlscan_en_main; while ( execute ) { char *p = buf + have; int space = bufsize - have; if ( space == 0 ) { /* We filled up the buffer trying to scan a token. Grow it. */ bufsize = bufsize * 2; char *newbuf = new char[bufsize]; /* Recompute p and space. */ p = newbuf + have; space = bufsize - have; /* Patch up pointers possibly in use. */ if ( ts != 0 ) ts = newbuf + ( ts - buf ); te = newbuf + ( te - buf ); /* Copy the new buffer in. */ memcpy( newbuf, buf, have ); delete[] buf; buf = newbuf; } input.read( p, space ); int len = input.gcount(); char *pe = p + len; /* If we see eof then append the eof var. */ char *eof = 0; if ( len == 0 ) { eof = pe; execute = false; } %% write exec; /* Check if we failed. */ if ( cs == rlscan_error ) { /* Machine failed before finding a token. I'm not yet sure if this * is reachable. */ scan_error() << "scanner error" << endl; exit(1); } /* Decide if we need to preserve anything. */ char *preserve = ts; /* Now set up the prefix. */ if ( preserve == 0 ) have = 0; else { /* There is data that needs to be shifted over. */ have = pe - preserve; memmove( buf, preserve, have ); unsigned int shiftback = preserve - buf; if ( ts != 0 ) ts -= shiftback; te -= shiftback; preserve = buf; } } delete[] buf; } ragel-6.10/ragel/rubyfflat.cpp0000664000175000017500000002452613065111230013252 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rubyfflat.h" void RubyFFlatCodeGen::GOTO( ostream &out, int gotoDest, bool inFinish ) { out << " begin\n" " " << vCS() << " = " << gotoDest << "\n" " _goto_level = _again\n" " next\n" " end\n"; } void RubyFFlatCodeGen::GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ) { out << " begin\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, 0, inFinish ); out << ")\n"; out << " _goto_level = _again\n" " next\n" " end\n"; } void RubyFFlatCodeGen::CALL( ostream &out, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << "+= 1\n" " " << vCS() << " = " << callDest << "\n" " _goto_level = _again\n" " next\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyFFlatCodeGen::CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << " += 1\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, targState, inFinish ); out << ")\n"; out << " _goto_level = _again\n" " next\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyFFlatCodeGen::RET( ostream &out, bool inFinish ) { out << " begin\n" " " << TOP() << " -= 1\n" " " << vCS() << " = " << STACK() << "[" << TOP() << "]\n"; if ( postPopExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, postPopExpr, 0, false ); out << "end\n"; } out << " _goto_level = _again\n" " next\n" " end\n"; } void RubyFFlatCodeGen::BREAK( ostream &out, int targState ) { out << " begin\n" " " << P() << " += 1\n" " _goto_level = _out\n" " next\n" " end\n"; } int RubyFFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; return act; } int RubyFFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; return act; } int RubyFFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; return act; } /* Write out the function for a transition. */ int RubyFFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; return action; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &RubyFFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &RubyFFlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyFFlatCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &RubyFFlatCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; } void RubyFFlatCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void RubyFFlatCodeGen::writeExec() { out << "begin\n" " testEof = false\n" " _slen, _trans, _keys, _inds"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; if ( redFsm->anyConditions() ) out << ", _cond, _conds, _widec"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) out << ", _acts, _nacts"; out << " = nil\n"; out << " _goto_level = 0\n" " _resume = 10\n" " _eof_trans = 15\n" " _again = 20\n" " _test_eof = 30\n" " _out = 40\n"; out << " while true\n" " if _goto_level <= 0\n"; if ( !noEnd ) { out << " if " << P() << " == " << PE() << "\n" " _goto_level = _test_eof\n" " next\n" " end\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } /* The resume label. */ out << " end\n" " if _goto_level <= _resume\n"; if ( redFsm->anyFromStateActions() ) { out << " case " << FSA() << "[" << vCS() << "] \n"; FROM_STATE_ACTION_SWITCH() << " end\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) { out << " end\n" " if _goto_level <= _eof_trans\n"; } if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << "\n"; out << " " << vCS() << " = " << TT() << "[_trans]\n"; if ( redFsm->anyRegActions() ) { /* break _again */ out << " if " << TA() << "[_trans] != 0\n" " case " << TA() << "[_trans]" << "\n"; ACTION_SWITCH() << " end\n" " end\n"; } /* The again label. */ out << " end\n" " if _goto_level <= _again\n"; if ( redFsm->anyToStateActions() ) { out << " case " << TSA() << "[" << vCS() << "] \n"; TO_STATE_ACTION_SWITCH() << " end\n" "\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } out << " " << P() << " += 1\n"; if ( !noEnd ) { out << " if " << P() << " != " << PE() << "\n" " _goto_level = _resume\n" " next\n" " end\n"; } else { out << " _goto_level = _resume\n" " next\n"; } /* The test eof label. */ out << " end\n" " if _goto_level <= _test_eof\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << "\n"; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " _goto_level = _eof_trans\n" " next;\n" " end\n"; } if ( redFsm->anyEofActions() ) { out << " case " << EA() << "[" << vCS() << "]\n"; EOF_ACTION_SWITCH() << " end\n"; } out << " end\n" "\n"; } out << " end\n" " if _goto_level <= _out\n" " break\n" " end\n" "end\n"; /* Wrapping the execute block. */ out << " end\n"; } /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/csflat.cpp0000664000175000017500000005201413065111230012521 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "csflat.h" #include "redfsm.h" #include "gendata.h" std::ostream &CSharpFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &CSharpFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &CSharpFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &CSharpFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &CSharpFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpFlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpFlatCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, true ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpFlatCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpFlatCodeGen::FLAT_INDEX_OFFSET() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ if ( st->transList != 0 ) curIndOffset += keyOps->span( st->lowKey, st->highKey ); if ( st->defTrans != 0 ) curIndOffset += 1; } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::KEY_SPANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->transList != 0 ) span = keyOps->span( st->lowKey, st->highKey ); out << span; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::TO_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::FROM_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::EOF_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::EOF_TRANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::COND_KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just cond low key and cond high key. */ out << ALPHA_KEY( st->condLowKey ) << ", "; out << ALPHA_KEY( st->condHighKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ if ( keyOps->alphType->isChar ) out << "(char) " << 0 << "\n"; else out << 0 << "\n"; return out; } std::ostream &CSharpFlatCodeGen::COND_KEY_SPANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->condList != 0 ) span = keyOps->span( st->condLowKey, st->condHighKey ); out << span; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::CONDS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->condList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->condList[pos] != 0 ) out << st->condList[pos]->condSpaceId + 1 << ", "; else out << "0, "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &CSharpFlatCodeGen::COND_INDEX_OFFSET() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ if ( st->condList != 0 ) curIndOffset += keyOps->span( st->condLowKey, st->condHighKey ); } out << "\n"; return out; } std::ostream &CSharpFlatCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just low key and high key. */ out << ALPHA_KEY( st->lowKey ) << ", "; out << ALPHA_KEY( st->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ if ( keyOps->alphType->isChar ) out << "(char) " << 0 << "\n"; else out << 0 << "\n"; return out; } std::ostream &CSharpFlatCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->transList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->lowKey, st->highKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { out << st->transList[pos]->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* The state's default index goes next. */ if ( st->defTrans != 0 ) out << st->defTrans->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &CSharpFlatCodeGen::TRANS_TARGS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } std::ostream &CSharpFlatCodeGen::TRANS_ACTIONS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } void CSharpFlatCodeGen::LOCATE_TRANS() { out << " _keys = " << vCS() << "<<1;\n" " _inds = " << IO() << "[" << vCS() << "];\n" "\n" " _slen = " << SP() << "[" << vCS() << "];\n" " _trans = " << I() << "[_inds + (\n" " _slen > 0 && " << K() << "[_keys] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= " << K() <<"[_keys+1] ?\n" " " << GET_WIDE_KEY() << " - " << K() << "[_keys] : _slen ) ];\n" "\n"; } void CSharpFlatCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{" << vCS() << " = " << gotoDest << "; " << CTRL_FLOW() << "goto _again;}"; } void CSharpFlatCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{" << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << "goto _again;}"; } void CSharpFlatCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void CSharpFlatCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void CSharpFlatCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void CSharpFlatCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void CSharpFlatCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << "; " << CTRL_FLOW() << "goto _again;}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpFlatCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << "); " << CTRL_FLOW() << "goto _again;}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpFlatCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];"; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "}"; } ret << CTRL_FLOW() << "goto _again;}"; } void CSharpFlatCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }"; } void CSharpFlatCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void CSharpFlatCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << ";\n"; out << " _keys = " << vCS() << "<<1;\n" " _conds = " << CO() << "[" << vCS() << "];\n" // " _keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n" // " _conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n" "\n" " _slen = " << CSP() << "[" << vCS() << "];\n" " if (_slen > 0 && " << CK() << "[_keys] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= " << CK() << "[_keys+1])\n" " _cond = " << C() << "[_conds+" << GET_WIDE_KEY() << " - " << CK() << "[_keys]];\n" " else\n" " _cond = 0;" "\n"; /* XXX This version of the code doesn't work because Mono is weird. Works * fine in Microsoft's csc, even though the bug report filed claimed it * didn't. " _slen = " << CSP() << "[" << vCS() << "];\n" " _cond = _slen > 0 && " << CK() << "[_keys] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= " << CK() << "[_keys+1] ?\n" " " << C() << "[_conds+" << GET_WIDE_KEY() << " - " << CK() << "[_keys]] : 0;\n" "\n"; */ out << " switch ( _cond ) {\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId + 1 << ": {\n"; out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } out << " }\n"; out << " break;\n"; } SWITCH_DEFAULT(); out << " }\n"; } void CSharpFlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " {\n" " " << slenType << " _slen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n" " " << transType << " _trans"; if ( redFsm->anyConditions() ) out << ", _cond"; out << ";\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " int _acts;\n" " int _nacts;\n"; } out << " " << "int _keys;\n" " " << indsType << " _inds;\n"; /* " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n" " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/ if ( redFsm->anyConditions() ) { out << " " << condsType << " _conds;\n" " " << WIDE_ALPH_TYPE() << " _widec;\n"; } out << "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << FSA() << "[" << vCS() << "];\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " _acts = " << TA() << "[_trans];\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] )\n {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << TSA() << "[" << vCS() << "];\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << CAST(transType) << " (" << ET() << "[" << vCS() << "] - 1);\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "__acts = " << EA() << "[" << vCS() << "];\n" " " << UINT() << " __nacts = " << CAST(UINT()) << " " << A() << "[__acts++];\n" " while ( __nacts-- > 0 ) {\n" " switch ( " << A() << "[__acts++] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } void CSharpFlatCodeGen::initVarTypes() { slenType = ARRAY_TYPE(MAX(redFsm->maxSpan, redFsm->maxCondSpan)); transType = ARRAY_TYPE(redFsm->maxIndex+1); indsType = ARRAY_TYPE(redFsm->maxFlatIndexOffset); condsType = ARRAY_TYPE(redFsm->maxCondIndexOffset); } ragel-6.10/ragel/dotcodegen.cpp0000664000175000017500000002034313065111230013360 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "dotcodegen.h" #include "gendata.h" using std::istream; using std::ifstream; using std::ostream; using std::ios; using std::cin; using std::cout; using std::cerr; using std::endl; /* Override this so that write statement processing is ignored */ bool GraphvizDotGen::writeStatement( InputLoc &, int, char ** ) { return false; } std::ostream &GraphvizDotGen::KEY( Key key ) { if ( displayPrintables && key.isPrintable() ) { // Output values as characters, ensuring we escape the quote (") character char cVal = (char) key.getVal(); switch ( cVal ) { case '"': case '\\': out << "'\\" << cVal << "'"; break; case '\a': out << "'\\\\a'"; break; case '\b': out << "'\\\\b'"; break; case '\t': out << "'\\\\t'"; break; case '\n': out << "'\\\\n'"; break; case '\v': out << "'\\\\v'"; break; case '\f': out << "'\\\\f'"; break; case '\r': out << "'\\\\r'"; break; case ' ': out << "SP"; break; default: out << "'" << cVal << "'"; break; } } else { if ( keyOps->isSigned ) out << key.getVal(); else out << (unsigned long) key.getVal(); } return out; } std::ostream &GraphvizDotGen::TRANS_ACTION( RedStateAp *fromState, RedTransAp *trans ) { int n = 0; RedAction *actions[3]; if ( fromState->fromStateAction != 0 ) actions[n++] = fromState->fromStateAction; if ( trans->action != 0 ) actions[n++] = trans->action; if ( trans->targ != 0 && trans->targ->toStateAction != 0 ) actions[n++] = trans->targ->toStateAction; if ( n > 0 ) out << " / "; /* Loop the existing actions and write out what's there. */ for ( int a = 0; a < n; a++ ) { for ( GenActionTable::Iter actIt = actions[a]->key.first(); actIt.lte(); actIt++ ) { GenAction *action = actIt->value; out << action->nameOrLoc(); if ( a < n-1 || !actIt.last() ) out << ", "; } } return out; } std::ostream &GraphvizDotGen::ACTION( RedAction *action ) { /* The action. */ out << " / "; for ( GenActionTable::Iter actIt = action->key.first(); actIt.lte(); actIt++ ) { GenAction *action = actIt->value; if ( action->name != 0 ) out << action->name; else out << action->loc.line << ":" << action->loc.col; if ( !actIt.last() ) out << ", "; } return out; } std::ostream &GraphvizDotGen::ONCHAR( Key lowKey, Key highKey ) { GenCondSpace *condSpace; if ( lowKey > keyOps->maxKey && (condSpace=findCondSpace(lowKey, highKey) ) ) { Key values = ( lowKey - condSpace->baseKey ) / keyOps->alphSize(); lowKey = keyOps->minKey + (lowKey - condSpace->baseKey - keyOps->alphSize() * values.getVal()); highKey = keyOps->minKey + (highKey - condSpace->baseKey - keyOps->alphSize() * values.getVal()); KEY( lowKey ); if ( lowKey != highKey ) { out << ".."; KEY( highKey ); } out << "("; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { bool set = values & (1 << csi.pos()); if ( !set ) out << "!"; out << (*csi)->nameOrLoc(); if ( !csi.last() ) out << ", "; } out << ")"; } else { /* Output the key. Possibly a range. */ KEY( lowKey ); if ( highKey != lowKey ) { out << ".."; KEY( highKey ); } } return out; } void GraphvizDotGen::writeTransList( RedStateAp *state ) { /* Build the set of unique transitions out of this state. */ RedTransSet stTransSet; for ( RedTransList::Iter tel = state->outRange; tel.lte(); tel++ ) { /* If we haven't seen the transitions before, the move forward * emitting all the transitions on the same character. */ if ( stTransSet.insert( tel->value ) ) { /* Write out the from and to states. */ out << "\t" << state->id << " -> "; if ( tel->value->targ == 0 ) out << "err_" << state->id; else out << tel->value->targ->id; /* Begin the label. */ out << " [ label = \""; ONCHAR( tel->lowKey, tel->highKey ); /* Walk the transition list, finding the same. */ for ( RedTransList::Iter mtel = tel.next(); mtel.lte(); mtel++ ) { if ( mtel->value == tel->value ) { out << ", "; ONCHAR( mtel->lowKey, mtel->highKey ); } } /* Write the action and close the transition. */ TRANS_ACTION( state, tel->value ); out << "\" ];\n"; } } /* Write the default transition. */ if ( state->defTrans != 0 ) { /* Write out the from and to states. */ out << "\t" << state->id << " -> "; if ( state->defTrans->targ == 0 ) out << "err_" << state->id; else out << state->defTrans->targ->id; /* Begin the label. */ out << " [ label = \"DEF"; /* Write the action and close the transition. */ TRANS_ACTION( state, state->defTrans ); out << "\" ];\n"; } } void GraphvizDotGen::writeDotFile( ) { out << "digraph " << fsmName << " {\n" " rankdir=LR;\n"; /* Define the psuedo states. Transitions will be done after the states * have been defined as either final or not final. */ out << " node [ shape = point ];\n"; if ( redFsm->startState != 0 ) out << " ENTRY;\n"; /* Psuedo states for entry points in the entry map. */ for ( EntryIdVect::Iter en = entryPointIds; en.lte(); en++ ) { RedStateAp *state = allStates + *en; out << " en_" << state->id << ";\n"; } /* Psuedo states for final states with eof actions. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 && st->eofTrans->action != 0 ) out << " eof_" << st->id << ";\n"; if ( st->eofAction != 0 ) out << " eof_" << st->id << ";\n"; } out << " node [ shape = circle, height = 0.2 ];\n"; /* Psuedo states for states whose default actions go to error. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { bool needsErr = false; if ( st->defTrans != 0 && st->defTrans->targ == 0 ) needsErr = true; else { for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) { if ( tel->value->targ == 0 ) { needsErr = true; break; } } } if ( needsErr ) out << " err_" << st->id << " [ label=\"\"];\n"; } /* Attributes common to all nodes, plus double circle for final states. */ out << " node [ fixedsize = true, height = 0.65, shape = doublecircle ];\n"; /* List Final states. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->isFinal ) out << " " << st->id << ";\n"; } /* List transitions. */ out << " node [ shape = circle ];\n"; /* Walk the states. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) writeTransList( st ); /* Transitions into the start state. */ if ( redFsm->startState != 0 ) out << " ENTRY -> " << redFsm->startState->id << " [ label = \"IN\" ];\n"; /* Transitions into the entry points. */ for ( EntryIdVect::Iter en = entryPointIds; en.lte(); en++ ) { RedStateAp *state = allStates + *en; char *name = entryPointNames[en.pos()]; out << " en_" << state->id << " -> " << state->id << " [ label = \"" << name << "\" ];\n"; } /* Out action transitions. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 && st->eofTrans->action != 0 ) { out << " " << st->id << " -> eof_" << st->id << " [ label = \"EOF"; ACTION( st->eofTrans->action ) << "\" ];\n"; } if ( st->eofAction != 0 ) { out << " " << st->id << " -> eof_" << st->id << " [ label = \"EOF"; ACTION( st->eofAction ) << "\" ];\n"; } } out << "}\n"; } void GraphvizDotGen::finishRagelDef() { /* For dot file generation we want to pick default transitions. */ redFsm->chooseDefaultSpan(); } ragel-6.10/ragel/csgoto.cpp0000664000175000017500000005275013065111230012552 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "csgoto.h" #include "redfsm.h" #include "bstmap.h" #include "gendata.h" /* Emit the goto to take for a given transition. */ std::ostream &CSharpGotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { out << TABS(level) << "goto tr" << trans->id << ";"; return out; } std::ostream &CSharpGotoCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpGotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpGotoCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, true ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpGotoCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } void CSharpGotoCodeGen::GOTO_HEADER( RedStateAp *state ) { /* Label the state. */ out << "case " << state->id << ":\n"; } void CSharpGotoCodeGen::emitSingleSwitch( RedStateAp *state ) { /* Load up the singles. */ int numSingles = state->outSingle.length(); RedTransEl *data = state->outSingle.data; if ( numSingles == 1 ) { /* If there is a single single key then write it out as an if. */ out << "\tif ( " << GET_WIDE_KEY(state) << " == " << KEY(data[0].lowKey) << " )\n\t\t"; /* Virtual function for writing the target of the transition. */ TRANS_GOTO(data[0].value, 0) << "\n"; } else if ( numSingles > 1 ) { /* Write out single keys in a switch if there is more than one. */ out << "\tswitch( " << GET_WIDE_KEY(state) << " ) {\n"; /* Write out the single indicies. */ for ( int j = 0; j < numSingles; j++ ) { out << "\t\tcase " << ALPHA_KEY(data[j].lowKey) << ": "; TRANS_GOTO(data[j].value, 0) << "\n"; } /* Emits a default case for D code. */ SWITCH_DEFAULT(); /* Close off the transition switch. */ out << "\t}\n"; } } void CSharpGotoCodeGen::emitRangeBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; RedTransEl *data = state->outRange.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid].lowKey == keyOps->minKey; bool limitHigh = data[mid].highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " < " << KEY(data[mid].lowKey) << " ) {\n"; emitRangeBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "} else if ( " << GET_WIDE_KEY(state) << " > " << KEY(data[mid].highKey) << " ) {\n"; emitRangeBSearch( state, level+1, mid+1, high ); out << TABS(level) << "} else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " < " << KEY(data[mid].lowKey) << " ) {\n"; emitRangeBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "} else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << "} else if ( " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " > " << KEY(data[mid].highKey) << " ) {\n"; emitRangeBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "} else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << "} else if ( " << GET_WIDE_KEY(state) << " >= " << KEY(data[mid].lowKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " && " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if ( " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { /* Both high and low are at the limit. No tests to do. */ TRANS_GOTO(data[mid].value, level+1) << "\n"; } } } void CSharpGotoCodeGen::STATE_GOTO_ERROR() { /* Label the state and bail immediately. */ outLabelUsed = true; RedStateAp *state = redFsm->errState; out << "case " << state->id << ":\n"; out << " goto _out;\n"; } void CSharpGotoCodeGen::COND_TRANSLATE( GenStateCond *stateCond, int level ) { GenCondSpace *condSpace = stateCond->condSpace; out << TABS(level) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(level) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } } void CSharpGotoCodeGen::emitCondBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; GenStateCond **data = state->stateCondVect.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid]->lowKey == keyOps->minKey; bool limitHigh = data[mid]->highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if ( " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " ) {\n"; emitCondBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "} else if ( " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " ) {\n"; emitCondBSearch( state, level+1, mid+1, high ); out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if ( " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " ) {\n"; emitCondBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { out << TABS(level) << "} else if ( " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if ( " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " ) {\n"; emitCondBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "} else {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { out << TABS(level) << "} else if ( " << GET_KEY() << " >= " << KEY(data[mid]->lowKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " && " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if ( " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " ) {\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if ( " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " )\n {"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "}\n"; } else { /* Both high and low are at the limit. No tests to do. */ COND_TRANSLATE(data[mid], level); } } } std::ostream &CSharpGotoCodeGen::STATE_GOTOS() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st == redFsm->errState ) STATE_GOTO_ERROR(); else { /* Writing code above state gotos. */ GOTO_HEADER( st ); if ( st->stateCondVect.length() > 0 ) { out << " _widec = " << GET_KEY() << ";\n"; emitCondBSearch( st, 1, 0, st->stateCondVect.length() - 1 ); } /* Try singles. */ if ( st->outSingle.length() > 0 ) emitSingleSwitch( st ); /* Default case is to binary search for the ranges, if that fails then */ if ( st->outRange.length() > 0 ) emitRangeBSearch( st, 1, 0, st->outRange.length() - 1 ); /* Write the default transition. */ TRANS_GOTO( st->defTrans, 1 ) << "\n"; } } return out; } std::ostream &CSharpGotoCodeGen::TRANSITIONS() { /* Emit any transitions that have functions and that go to * this state. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Write the label for the transition so it can be jumped to. */ out << " tr" << trans->id << ": "; /* Destination state. */ if ( trans->action != 0 && trans->action->anyCurStateRef() ) out << "_ps = " << vCS() << ";"; out << vCS() << " = " << trans->targ->id << "; "; if ( trans->action != 0 ) { /* Write out the transition func. */ out << "goto f" << trans->action->actListId << ";\n"; } else { /* No code to execute, just loop around. */ out << "goto _again;\n"; } } return out; } std::ostream &CSharpGotoCodeGen::EXEC_FUNCS() { /* Make labels that set acts and jump to execFuncs. Loop func indicies. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { out << " f" << redAct->actListId << ": " << "_acts = " << itoa( redAct->location+1 ) << ";" " goto execFuncs;\n"; } } out << "\n" "execFuncs:\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" " goto _again;\n"; return out; } unsigned int CSharpGotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; return act; } unsigned int CSharpGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; return act; } unsigned int CSharpGotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; return act; } std::ostream &CSharpGotoCodeGen::TO_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = TO_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &CSharpGotoCodeGen::FROM_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = FROM_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &CSharpGotoCodeGen::EOF_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = EOF_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &CSharpGotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << "\t\tcase " << st->id << ": "; /* Write the goto func. */ out << "goto f" << st->eofAction->actListId << ";\n"; } } return out; } void CSharpGotoCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{" << vCS() << " = " << gotoDest << "; " << CTRL_FLOW() << "goto _again;}"; } void CSharpGotoCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{" << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << "); " << CTRL_FLOW() << "goto _again;}"; } void CSharpGotoCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void CSharpGotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void CSharpGotoCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void CSharpGotoCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void CSharpGotoCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << "; " << CTRL_FLOW() << "goto _again;}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpGotoCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << "); " << CTRL_FLOW() << "goto _again;}"; if ( prePushExpr != 0 ) ret << "}"; } void CSharpGotoCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];"; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "}"; } ret << CTRL_FLOW() << "goto _again;}"; } void CSharpGotoCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }"; } void CSharpGotoCodeGen::writeData() { if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void CSharpGotoCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " " << ARRAY_TYPE(redFsm->maxActionLoc) << " _acts;\n" " " << ARRAY_TYPE(redFsm->maxActArrItem) << " _nacts;\n"; } if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; out << "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << FSA() << "[" << vCS() << "];\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } out << " switch ( " << vCS() << " ) {\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " }\n" "\n"; TRANSITIONS() << "\n"; if ( redFsm->anyRegActions() ) EXEC_FUNCS() << "\n"; out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << TSA() << "[" << vCS() << "];\n" " _nacts = " << A() << "[_acts++];\n" " while ( _nacts-- > 0 ) {\n" " switch ( " << A() << "[_acts++] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " switch ( " << vCS() << " ) {\n"; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " case " << st->id << ": goto tr" << st->eofTrans->id << ";\n"; } SWITCH_DEFAULT() << " }\n"; } if ( redFsm->anyEofActions() ) { out << " " << ARRAY_TYPE(redFsm->maxActionLoc) << " __acts = " << EA() << "[" << vCS() << "];\n" " " << ARRAY_TYPE(redFsm->maxActArrItem) << " __nacts = " << A() << "[__acts++];\n" " while ( __nacts-- > 0 ) {\n" " switch ( " << A() << "[__acts++] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/cdftable.h0000664000175000017500000000425013065111230012455 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDFTABLE_H #define _CDFTABLE_H #include #include "cdtable.h" /* Forwards. */ struct CodeGenData; /* * FTabCodeG\verb|e */ class FTabCodeGen : public TabCodeGen { protected: FTabCodeGen( ostream &out ) : FsmCodeGen(out), TabCodeGen(out) {} std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); virtual void calcIndexSize(); }; /* * CFTabCodeGen */ struct CFTabCodeGen : public FTabCodeGen, public CCodeGen { CFTabCodeGen( ostream &out ) : FsmCodeGen(out), FTabCodeGen(out), CCodeGen(out) {} }; /* * class DFTabCodeGen */ struct DFTabCodeGen : public FTabCodeGen, public DCodeGen { DFTabCodeGen( ostream &out ) : FsmCodeGen(out), FTabCodeGen(out), DCodeGen(out) {} }; /* * class D2FTabCodeGen */ struct D2FTabCodeGen : public FTabCodeGen, public D2CodeGen { D2FTabCodeGen( ostream &out ) : FsmCodeGen(out), FTabCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/gotablish.cpp0000664000175000017500000000633613065111230013227 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "gotablish.h" using std::endl; void GoTablishCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << vCS() << " = " << gotoDest << endl << "goto _again" << endl; } void GoTablishCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ")" << endl << "goto _again" << endl; } void GoTablishCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void GoTablishCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void GoTablishCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << endl; } void GoTablishCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ")" << endl; } void GoTablishCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{ "; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << STACK() << "[" << TOP() << "] = " << vCS() << "; " << TOP() << "++; " << vCS() << " = " << callDest << "; " << "goto _again" << endl; if ( prePushExpr != 0 ) ret << " }"; } void GoTablishCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << STACK() << "[" << TOP() << "] = " << vCS() << "; " << TOP() << "++; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish, false ); ret << "); " << "goto _again" << endl; if ( prePushExpr != 0 ) ret << "}"; } void GoTablishCodeGen::RET( ostream &ret, bool inFinish ) { ret << TOP() << "--; " << vCS() << " = " << STACK() << "[" << TOP() << "]" << endl; if ( postPopExpr != 0 ) { ret << "{ "; INLINE_LIST( ret, postPopExpr, 0, false, false ); ret << " }" << endl; } ret << "goto _again" << endl; } void GoTablishCodeGen::BREAK( ostream &ret, int targState, bool csForced ) { outLabelUsed = true; ret << P() << "++; " << "goto _out" << endl; } ragel-6.10/ragel/csftable.cpp0000664000175000017500000002403013065111230013025 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "csftable.h" #include "redfsm.h" #include "gendata.h" /* Determine if we should use indicies or not. */ void CSharpFTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActListId) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActListId) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &CSharpFTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &CSharpFTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &CSharpFTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &CSharpFTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &CSharpFTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &CSharpFTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &CSharpFTabCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &CSharpFTabCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } void CSharpFTabCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void CSharpFTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; initVarTypes(); out << " {\n" " " << klenType << " _klen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n" " " << keysType << " _keys;\n" " " << transType << " _trans;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; out << "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " switch ( " << FSA() << "[" << vCS() << "] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); out << "_match:\n"; if ( useIndicies ) out << " _trans = " << CAST(transType) << I() << "[_trans];\n"; if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " switch ( " << TA() << "[_trans] ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " switch ( " << TSA() << "[" << vCS() << "] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << CAST(transType) << " (" << ET() << "[" << vCS() << "] - 1);\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " switch ( " << EA() << "[" << vCS() << "] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/common.h0000664000175000017500000002167613065111230012214 00000000000000/* * Copyright 2001-2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _COMMON_H #define _COMMON_H #include #include #include "dlist.h" /* Location in an input file. */ struct InputLoc { const char *fileName; long line; long col; }; typedef unsigned long long Size; struct Key { private: long key; public: friend inline Key operator+(const Key key1, const Key key2); friend inline Key operator-(const Key key1, const Key key2); friend inline Key operator/(const Key key1, const Key key2); friend inline long operator&(const Key key1, const Key key2); friend inline bool operator<( const Key key1, const Key key2 ); friend inline bool operator<=( const Key key1, const Key key2 ); friend inline bool operator>( const Key key1, const Key key2 ); friend inline bool operator>=( const Key key1, const Key key2 ); friend inline bool operator==( const Key key1, const Key key2 ); friend inline bool operator!=( const Key key1, const Key key2 ); friend struct KeyOps; Key( ) {} Key( const Key &key ) : key(key.key) {} Key( long key ) : key(key) {} /* Returns the value used to represent the key. This value must be * interpreted based on signedness. */ long getVal() const { return key; }; /* Returns the key casted to a long long. This form of the key does not * require any signedness interpretation. */ long long getLongLong() const; /* Returns the distance from the key value to the maximum value that the * key implementation can hold. */ Size availableSpace() const; bool isUpper() const { return ( 'A' <= key && key <= 'Z' ); } bool isLower() const { return ( 'a' <= key && key <= 'z' ); } bool isPrintable() const { return ( 7 <= key && key <= 13 ) || ( 32 <= key && key < 127 ); } Key toUpper() const { return Key( 'A' + ( key - 'a' ) ); } Key toLower() const { return Key( 'a' + ( key - 'A' ) ); } void operator+=( const Key other ) { /* FIXME: must be made aware of isSigned. */ key += other.key; } void operator-=( const Key other ) { /* FIXME: must be made aware of isSigned. */ key -= other.key; } void operator|=( const Key other ) { /* FIXME: must be made aware of isSigned. */ key |= other.key; } /* Decrement. Needed only for ranges. */ inline void decrement(); inline void increment(); }; struct HostType { const char *data1; const char *data2; const char *internalName; bool isSigned; bool isOrd; bool isChar; long long sMinVal; long long sMaxVal; unsigned long long uMinVal; unsigned long long uMaxVal; unsigned int size; }; struct HostLang { /* Target language. */ enum Lang { C, D, D2, Go, Java, Ruby, CSharp, OCaml }; Lang lang; HostType *hostTypes; int numHostTypes; HostType *defaultAlphType; bool explicitUnsigned; }; extern HostLang *hostLang; extern HostLang hostLangC; extern HostLang hostLangD; extern HostLang hostLangD2; extern HostLang hostLangGo; extern HostLang hostLangJava; extern HostLang hostLangRuby; extern HostLang hostLangCSharp; extern HostLang hostLangOCaml; HostType *findAlphType( const char *s1 ); HostType *findAlphType( const char *s1, const char *s2 ); HostType *findAlphTypeInternal( const char *s1 ); /* An abstraction of the key operators that manages key operations such as * comparison and increment according the signedness of the key. */ struct KeyOps { /* Default to signed alphabet. */ KeyOps() : isSigned(true), alphType(0) {} /* Default to signed alphabet. */ KeyOps( bool isSigned ) :isSigned(isSigned) {} bool isSigned; Key minKey, maxKey; HostType *alphType; void setAlphType( HostType *alphType ) { this->alphType = alphType; isSigned = alphType->isSigned; if ( isSigned ) { minKey = (long) alphType->sMinVal; maxKey = (long) alphType->sMaxVal; } else { minKey = (long) (unsigned long) alphType->uMinVal; maxKey = (long) (unsigned long) alphType->uMaxVal; } } /* Compute the distance between two keys. */ Size span( Key key1, Key key2 ) { return isSigned ? (unsigned long long)( (long long)key2.key - (long long)key1.key + 1) : (unsigned long long)( (unsigned long)key2.key) - (unsigned long long)((unsigned long)key1.key) + 1; } Size alphSize() { return span( minKey, maxKey ); } HostType *typeSubsumes( long long maxVal ) { HostType *hostTypes = hostLang->hostTypes; for ( int i = 0; i < hostLang->numHostTypes; i++ ) { long long typeMaxVal = hostTypes[i].isSigned ? hostTypes[i].sMaxVal : hostTypes[i].uMaxVal; if ( maxVal <= typeMaxVal ) return &hostLang->hostTypes[i]; } return 0; } HostType *typeSubsumes( bool isSigned, long long maxVal ) { HostType *hostTypes = hostLang->hostTypes; for ( int i = 0; i < hostLang->numHostTypes; i++ ) { long long typeMaxVal = hostTypes[i].isSigned ? hostTypes[i].sMaxVal : hostTypes[i].uMaxVal; if ( ( ( isSigned && hostTypes[i].isSigned ) || !isSigned ) && maxVal <= typeMaxVal ) return hostLang->hostTypes + i; } return 0; } }; extern KeyOps *keyOps; inline bool operator<( const Key key1, const Key key2 ) { return keyOps->isSigned ? key1.key < key2.key : (unsigned long)key1.key < (unsigned long)key2.key; } inline bool operator<=( const Key key1, const Key key2 ) { return keyOps->isSigned ? key1.key <= key2.key : (unsigned long)key1.key <= (unsigned long)key2.key; } inline bool operator>( const Key key1, const Key key2 ) { return keyOps->isSigned ? key1.key > key2.key : (unsigned long)key1.key > (unsigned long)key2.key; } inline bool operator>=( const Key key1, const Key key2 ) { return keyOps->isSigned ? key1.key >= key2.key : (unsigned long)key1.key >= (unsigned long)key2.key; } inline bool operator==( const Key key1, const Key key2 ) { return key1.key == key2.key; } inline bool operator!=( const Key key1, const Key key2 ) { return key1.key != key2.key; } /* Decrement. Needed only for ranges. */ inline void Key::decrement() { key = keyOps->isSigned ? key - 1 : ((unsigned long)key)-1; } /* Increment. Needed only for ranges. */ inline void Key::increment() { key = keyOps->isSigned ? key+1 : ((unsigned long)key)+1; } inline long long Key::getLongLong() const { return keyOps->isSigned ? (long long)key : (long long)(unsigned long)key; } inline Size Key::availableSpace() const { if ( keyOps->isSigned ) return (long long)LONG_MAX - (long long)key; else return (unsigned long long)ULONG_MAX - (unsigned long long)(unsigned long)key; } inline Key operator+(const Key key1, const Key key2) { /* FIXME: must be made aware of isSigned. */ return Key( key1.key + key2.key ); } inline Key operator-(const Key key1, const Key key2) { /* FIXME: must be made aware of isSigned. */ return Key( key1.key - key2.key ); } inline long operator&(const Key key1, const Key key2) { /* FIXME: must be made aware of isSigned. */ return key1.key & key2.key; } inline Key operator/(const Key key1, const Key key2) { /* FIXME: must be made aware of isSigned. */ return key1.key / key2.key; } /* Filter on the output stream that keeps track of the number of lines * output. */ class output_filter : public std::filebuf { public: output_filter( const char *fileName ) : fileName(fileName), line(1) { } virtual int sync(); virtual std::streamsize xsputn(const char* s, std::streamsize n); const char *fileName; int line; }; class cfilebuf : public std::streambuf { public: cfilebuf( char *fileName, FILE* file ) : fileName(fileName), file(file) { } char *fileName; FILE *file; int sync() { fflush( file ); return 0; } int overflow( int c ) { if ( c != EOF ) fputc( c, file ); return 0; } std::streamsize xsputn( const char* s, std::streamsize n ) { std::streamsize written = fwrite( s, 1, n, file ); return written; } }; class costream : public std::ostream { public: costream( cfilebuf *b ) : std::ostream(b), b(b) {} ~costream() { delete b; } void fclose() { ::fclose( b->file ); } cfilebuf *b; }; const char *findFileExtension( const char *stemFile ); const char *fileNameFromStem( const char *stemFile, const char *suffix ); struct Export { Export( const char *name, Key key ) : name(name), key(key) {} const char *name; Key key; Export *prev, *next; }; typedef DList ExportList; struct exit_object { }; extern exit_object endp; void operator<<( std::ostream &out, exit_object & ); #endif ragel-6.10/ragel/cdsplit.cpp0000664000175000017500000003255313065111230012715 00000000000000/* * Copyright 2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdsplit.h" #include "gendata.h" #include using std::ostream; using std::ios; using std::endl; /* Emit the goto to take for a given transition. */ std::ostream &SplitCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { if ( trans->targ->partition == currentPartition ) { if ( trans->action != 0 ) { /* Go to the transition which will go to the state. */ out << TABS(level) << "goto tr" << trans->id << ";"; } else { /* Go directly to the target state. */ out << TABS(level) << "goto st" << trans->targ->id << ";"; } } else { if ( trans->action != 0 ) { /* Go to the transition which will go to the state. */ out << TABS(level) << "goto ptr" << trans->id << ";"; trans->partitionBoundary = true; } else { /* Go directly to the target state. */ out << TABS(level) << "goto pst" << trans->targ->id << ";"; trans->targ->partitionBoundary = true; } } return out; } /* Called from before writing the gotos for each state. */ void SplitCodeGen::GOTO_HEADER( RedStateAp *state, bool stateInPartition ) { bool anyWritten = IN_TRANS_ACTIONS( state ); if ( state->labelNeeded ) out << "st" << state->id << ":\n"; if ( state->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->toStateAction->key; item.lte(); item++ ) { ACTION( out, item->value, state->id, false, state->toStateAction->anyNextStmt() ); } } /* Advance and test buffer pos. */ if ( state->labelNeeded ) { if ( !noEnd ) { out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _out" << state->id << ";\n"; } else { out << " " << P() << " += 1;\n"; } } /* Give the state a switch case. */ out << "case " << state->id << ":\n"; if ( state->fromStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->fromStateAction->key; item.lte(); item++ ) { ACTION( out, item->value, state->id, false, state->fromStateAction->anyNextStmt() ); } } if ( anyWritten ) genLineDirective( out ); /* Record the prev state if necessary. */ if ( state->anyRegCurStateRef() ) out << " _ps = " << state->id << ";\n"; } std::ostream &SplitCodeGen::STATE_GOTOS( int partition ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partition == partition ) { if ( st == redFsm->errState ) STATE_GOTO_ERROR(); else { /* We call into the base of the goto which calls back into us * using virtual functions. Set the current partition rather * than coding parameter passing throughout. */ currentPartition = partition; /* Writing code above state gotos. */ GOTO_HEADER( st, st->partition == partition ); if ( st->stateCondVect.length() > 0 ) { out << " _widec = " << GET_KEY() << ";\n"; emitCondBSearch( st, 1, 0, st->stateCondVect.length() - 1 ); } /* Try singles. */ if ( st->outSingle.length() > 0 ) emitSingleSwitch( st ); /* Default case is to binary search for the ranges, if that fails then */ if ( st->outRange.length() > 0 ) emitRangeBSearch( st, 1, 0, st->outRange.length() - 1 ); /* Write the default transition. */ TRANS_GOTO( st->defTrans, 1 ) << "\n"; } } } return out; } std::ostream &SplitCodeGen::PART_TRANS( int partition ) { for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { if ( trans->partitionBoundary ) { out << "ptr" << trans->id << ":\n"; if ( trans->action != 0 ) { /* If the action contains a next, then we must preload the current * state since the action may or may not set it. */ if ( trans->action->anyNextStmt() ) out << " " << vCS() << " = " << trans->targ->id << ";\n"; /* Write each action in the list. */ for ( GenActionTable::Iter item = trans->action->key; item.lte(); item++ ) { ACTION( out, item->value, trans->targ->id, false, trans->action->anyNextStmt() ); } } out << " goto pst" << trans->targ->id << ";\n"; trans->targ->partitionBoundary = true; } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partitionBoundary ) { out << " pst" << st->id << ":\n" " " << vCS() << " = " << st->id << ";\n"; if ( st->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ for ( GenActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) { ACTION( out, item->value, st->id, false, st->toStateAction->anyNextStmt() ); } genLineDirective( out ); } ptOutLabelUsed = true; out << " goto _pt_out; \n"; } } return out; } std::ostream &SplitCodeGen::EXIT_STATES( int partition ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->partition == partition && st->outNeeded ) { outLabelUsed = true; out << " _out" << st->id << ": " << vCS() << " = " << st->id << "; goto _out; \n"; } } return out; } std::ostream &SplitCodeGen::PARTITION( int partition ) { outLabelUsed = false; ptOutLabelUsed = false; /* Initialize the partition boundaries, which get set during the writing * of states. After the state writing we will */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->partitionBoundary = false; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->partitionBoundary = false; out << " " << ALPH_TYPE() << " *p = *_pp, *pe = *_ppe;\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( useAgainLabel() ) { out << " goto _resume;\n" "\n" "_again:\n" " switch ( " << vCS() << " ) {\n"; AGAIN_CASES() << " default: break;\n" " }\n" "\n"; if ( !noEnd ) { outLabelUsed = true; out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _out;\n"; } else { out << " " << P() << " += 1;\n"; } out << "_resume:\n"; } out << " switch ( " << vCS() << " )\n {\n"; STATE_GOTOS( partition ); SWITCH_DEFAULT() << " }\n"; PART_TRANS( partition ); EXIT_STATES( partition ); if ( outLabelUsed ) { out << "\n" " _out:\n" " *_pp = p;\n" " *_ppe = pe;\n" " return 0;\n"; } if ( ptOutLabelUsed ) { out << "\n" " _pt_out:\n" " *_pp = p;\n" " *_ppe = pe;\n" " return 1;\n"; } return out; } std::ostream &SplitCodeGen::PART_MAP() { int *partMap = new int[redFsm->stateList.length()]; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) partMap[st->id] = st->partition; out << "\t"; int totalItem = 0; for ( int i = 0; i < redFsm->stateList.length(); i++ ) { out << partMap[i]; if ( i != redFsm->stateList.length() - 1 ) { out << ", "; if ( ++totalItem % IALL == 0 ) out << "\n\t"; } } delete[] partMap; return out; } void SplitCodeGen::writeData() { out << "static const int " << START() << " = " << START_STATE_ID() << ";\n" "\n"; if ( !noFinal ) { out << "static const int " << FIRST_FINAL() << " = " << FIRST_FINAL_STATE() << ";\n" "\n"; } if ( !noError ) { out << "static const int " << ERROR() << " = " << ERROR_STATE() << ";\n" "\n"; } OPEN_ARRAY( ARRAY_TYPE(numSplitPartitions), PM() ); PART_MAP(); CLOSE_ARRAY() << "\n"; for ( int p = 0; p < redFsm->nParts; p++ ) { out << "int partition" << p << "( " << ALPH_TYPE() << " **_pp, " << ALPH_TYPE() << " **_ppe, struct " << FSM_NAME() << " *fsm );\n"; } out << "\n"; } std::ostream &SplitCodeGen::ALL_PARTITIONS() { /* compute the format string. */ int width = 0, high = redFsm->nParts - 1; while ( high > 0 ) { width++; high /= 10; } assert( width <= 8 ); char suffFormat[] = "_%6.6d.c"; suffFormat[2] = suffFormat[4] = ( '0' + width ); for ( int p = 0; p < redFsm->nParts; p++ ) { char suffix[10]; sprintf( suffix, suffFormat, p ); const char *fn = fileNameFromStem( sourceFileName, suffix ); const char *include = fileNameFromStem( sourceFileName, ".h" ); /* Create the filter on the output and open it. */ output_filter *partFilter = new output_filter( fn ); partFilter->open( fn, ios::out|ios::trunc ); if ( !partFilter->is_open() ) { error() << "error opening " << fn << " for writing" << endl; exit(1); } /* Attach the new file to the output stream. */ std::streambuf *prev_rdbuf = out.rdbuf( partFilter ); out << "#include \"" << include << "\"\n" "int partition" << p << "( " << ALPH_TYPE() << " **_pp, " << ALPH_TYPE() << " **_ppe, struct " << FSM_NAME() << " *fsm )\n" "{\n"; PARTITION( p ) << "}\n\n"; out.flush(); /* Fix the output stream. */ out.rdbuf( prev_rdbuf ); } return out; } void SplitCodeGen::writeExec() { /* Must set labels immediately before writing because we may depend on the * noend write option. */ setLabelsNeeded(); out << " {\n" " int _stat = 0;\n"; if ( !noEnd ) { out << " if ( " << P() << " == " << PE() << " )\n" " goto _out;\n"; } out << " goto _resume;\n"; /* In this reentry, to-state actions have already been executed on the * partition-switch exit from the last partition. */ out << "_reenter:\n"; if ( !noEnd ) { out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _out;\n"; } else { out << " " << P() << " += 1;\n"; } out << "_resume:\n"; out << " switch ( " << PM() << "[" << vCS() << "] ) {\n"; for ( int p = 0; p < redFsm->nParts; p++ ) { out << " case " << p << ":\n" " _stat = partition" << p << "( &p, &pe, fsm );\n" " break;\n"; } out << " }\n" " if ( _stat )\n" " goto _reenter;\n"; if ( !noEnd ) out << " _out: {}\n"; out << " }\n"; ALL_PARTITIONS(); } void SplitCodeGen::setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: { /* In split code gen we only need labels for transitions across * partitions. */ if ( fromState->partition == item->targState->partition ){ /* Mark the target as needing a label. */ item->targState->labelNeeded = true; } break; } default: break; } if ( item->children != 0 ) setLabelsNeeded( fromState, item->children ); } } void SplitCodeGen::setLabelsNeeded( RedStateAp *fromState, RedTransAp *trans ) { /* In the split code gen we don't need labels for transitions across * partitions. */ if ( fromState->partition == trans->targ->partition ) { /* If there is no action with a next statement, then the label will be * needed. */ trans->labelNeeded = true; if ( trans->action == 0 || !trans->action->anyNextStmt() ) trans->targ->labelNeeded = true; } /* Need labels for states that have goto or calls in action code * invoked on characters (ie, not from out action code). */ if ( trans->action != 0 ) { /* Loop the actions. */ for ( GenActionTable::Iter act = trans->action->key; act.lte(); act++ ) { /* Get the action and walk it's tree. */ setLabelsNeeded( fromState, act->value->inlineList ); } } } /* Set up labelNeeded flag for each state. */ void SplitCodeGen::setLabelsNeeded() { /* If we use the _again label, then we the _again switch, which uses all * labels. */ if ( useAgainLabel() ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = true; } else { /* Do not use all labels by default, init all labelNeeded vars to false. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = false; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) trans->labelNeeded = false; /* Walk all transitions and set only those that have targs. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { for ( RedTransList::Iter tel = st->outRange; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); for ( RedTransList::Iter tel = st->outSingle; tel.lte(); tel++ ) setLabelsNeeded( st, tel->value ); if ( st->defTrans != 0 ) setLabelsNeeded( st, st->defTrans ); } } if ( !noEnd ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->outNeeded = st->labelNeeded; } else { if ( redFsm->errState != 0 ) redFsm->errState->outNeeded = true; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Any state with a transition in that has a break will need an * out label. */ if ( trans->action != 0 && trans->action->anyBreakStmt() ) trans->targ->outNeeded = true; } } } ragel-6.10/ragel/csipgoto.h0000664000175000017500000000456113065111230012545 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _IPGCODEGEN_H #define _IPGCODEGEN_H #include #include "csgoto.h" /* Forwards. */ struct CodeGenData; /* * class CSharpIpGotoCodeGen */ class CSharpIpGotoCodeGen : public CSharpGotoCodeGen { public: CSharpIpGotoCodeGen( ostream &out ) : CSharpFsmCodeGen(out), CSharpGotoCodeGen(out) {} std::ostream &EXIT_STATES(); std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); std::ostream &FINISH_CASES(); std::ostream &AGAIN_CASES(); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void NEXT( ostream &ret, int nextDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void RET( ostream &ret, bool inFinish ); void CURS( ostream &ret, bool inFinish ); void TARGS( ostream &ret, bool inFinish, int targState ); void BREAK( ostream &ret, int targState ); virtual void writeData(); virtual void writeExec(); protected: bool useAgainLabel(); /* Called from GotoCodeGen::STATE_GOTOS just before writing the gotos for * each state. */ bool IN_TRANS_ACTIONS( RedStateAp *state ); void GOTO_HEADER( RedStateAp *state ); void STATE_GOTO_ERROR(); /* Set up labelNeeded flag for each state. */ void setLabelsNeeded( GenInlineList *inlineList ); void setLabelsNeeded(); }; #endif ragel-6.10/ragel/cdfflat.cpp0000664000175000017500000002112313065111230012645 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdfflat.h" #include "redfsm.h" #include "gendata.h" std::ostream &FFlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; out << act; return out; } std::ostream &FFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; out << act; return out; } std::ostream &FFlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; out << act; return out; } /* Write out the function for a transition. */ std::ostream &FFlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; out << action; return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FFlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FFlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FFlatCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FFlatCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } void FFlatCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void FFlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n" " int _slen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n"; out << " int _trans"; if ( redFsm->anyConditions() ) out << ", _cond"; out << ";\n"; out << " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_keys;\n" " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << PTR_CONST_END() << POINTER() << "_inds;\n"; if ( redFsm->anyConditions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxCond) << PTR_CONST_END() << POINTER() << "_conds;\n" " " << WIDE_ALPH_TYPE() << " _widec;\n"; } if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " switch ( " << FSA() << "[" << vCS() << "] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " switch ( " << TA() << "[_trans] ) {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " switch ( " << TSA() << "[" << vCS() << "] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " switch ( " << EA() << "[" << vCS() << "] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/gotable.cpp0000664000175000017500000006164713065111230012676 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "ragel.h" #include "gotable.h" #include "redfsm.h" #include "gendata.h" using std::endl; /* Determine if we should use indicies or not. */ void GoTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActionLoc) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActionLoc) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } std::ostream &GoTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &GoTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &GoTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &GoTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &GoTabCodeGen::TO_STATE_ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoTabCodeGen::FROM_STATE_ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, false, false ); } } genLineDirective( out ); return out; } std::ostream &GoTabCodeGen::EOF_ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, true, false ); } } genLineDirective(out); return out; } std::ostream &GoTabCodeGen::ACTION_SWITCH( int level ) { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << TABS(level) << "case " << act->actionId << ":" << endl; ACTION( out, act, 0, false, false ); } } genLineDirective(out); return out; } std::ostream &GoTabCodeGen::COND_OFFSETS() { out << " "; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } /* Move the key offset ahead. */ curKeyOffset += st->stateCondList.length(); } out << endl; return out; } std::ostream &GoTabCodeGen::KEY_OFFSETS() { out << " "; int totalStateNum = 0, curKeyOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the key offset. */ out << curKeyOffset; out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } /* Move the key offset ahead. */ curKeyOffset += st->outSingle.length() + st->outRange.length()*2; } out << endl; return out; } std::ostream &GoTabCodeGen::INDEX_OFFSETS() { out << " "; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } /* Move the index offset ahead. */ curIndOffset += st->outSingle.length() + st->outRange.length(); if ( st->defTrans != 0 ) curIndOffset += 1; } out << endl; return out; } std::ostream &GoTabCodeGen::COND_LENS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->stateCondList.length(); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::SINGLE_LENS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ out << st->outSingle.length(); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::RANGE_LENS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit length of range index. */ out << st->outRange.length(); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::TO_STATE_ACTIONS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::FROM_STATE_ACTIONS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::EOF_ACTIONS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::EOF_TRANS() { out << " "; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; out << ", "; if ( !st.last() ) { if ( ++totalStateNum % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::COND_KEYS() { out << " "; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Lower key. */ out << KEY( sc->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; /* Upper key. */ out << KEY( sc->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::COND_SPACES() { out << " "; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the state's transitions. */ for ( GenStateCondList::Iter sc = st->stateCondList; sc.lte(); sc++ ) { /* Cond Space id. */ out << sc->condSpace->condSpaceId << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::KEYS() { out << " "; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Loop the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << KEY( stel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* Loop the state's transitions. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { /* Lower key. */ out << KEY( rtel->lowKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; /* Upper key. */ out << KEY( rtel->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::INDICIES() { out << " "; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { out << stel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { out << rtel->value->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { out << st->defTrans->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::TRANS_TARGS() { out << " "; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* The state's default target state. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } /* Add any eof transitions that have not yet been written out above. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; trans->pos = totalTrans; out << trans->targ->id << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::TRANS_ACTIONS() { out << " "; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Walk the singles. */ for ( RedTransList::Iter stel = st->outSingle; stel.lte(); stel++ ) { RedTransAp *trans = stel->value; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* Walk the ranges. */ for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { RedTransAp *trans = rtel->value; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } /* The state's default index goes next. */ if ( st->defTrans != 0 ) { RedTransAp *trans = st->defTrans; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } /* Add any eof transitions that have not yet been written out above. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) { RedTransAp *trans = st->eofTrans; TRANS_ACTION( trans ) << ", "; if ( ++totalTrans % IALL == 0 ) out << endl << " "; } } out << endl; return out; } std::ostream &GoTabCodeGen::TRANS_TARGS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << " "; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Record the position, need this for eofTrans. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id << ", "; if ( t < redFsm->transSet.length()-1 ) { if ( ++totalStates % IALL == 0 ) out << endl << " "; } } out << endl; delete[] transPtrs; return out; } std::ostream &GoTabCodeGen::TRANS_ACTIONS_WI() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << " "; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); out << ", "; if ( t < redFsm->transSet.length()-1 ) { if ( ++totalAct % IALL == 0 ) out << endl << " "; } } out << endl; delete[] transPtrs; return out; } void GoTabCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << endl; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << endl; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << endl; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << endl; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << endl; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << endl; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << endl; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << endl; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << endl; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << endl; } STATE_IDS(); } void GoTabCodeGen::LOCATE_TRANS() { out << " _keys = " << CAST(INT(), KO() + "[" + vCS() + "]") << endl << " _trans = " << CAST(INT(), IO() + "[" + vCS() + "]") << endl << endl << " _klen = " << CAST(INT(), SL() + "[" + vCS() + "]") << endl << " if _klen > 0 {" << endl << " _lower := " << CAST(INT(), "_keys") << endl << " var _mid " << INT() << endl << " _upper := " << CAST(INT(), "_keys + _klen - 1") << endl << " for {" << endl << " if _upper < _lower {" << endl << " break" << endl << " }" << endl << endl << " _mid = _lower + ((_upper - _lower) >> 1)" << endl << " switch {" << endl << " case " << GET_WIDE_KEY() << " < " << K() << "[_mid]" << ":" << endl << " _upper = _mid - 1" << endl << " case " << GET_WIDE_KEY() << " > " << K() << "[_mid]" << ":" << endl << " _lower = _mid + 1" << endl << " default:" << endl << " _trans += " << CAST(INT(), "_mid - " + CAST(INT(), "_keys")) << endl << " goto _match" << endl << " }" << endl << " }" << endl << " _keys += _klen" << endl << " _trans += _klen" << endl << " }" << endl << endl << " _klen = " << CAST(INT(), RL() + "[" + vCS() + "]") << endl << " if _klen > 0 {" << endl << " _lower := " << CAST(INT(), "_keys") << endl << " var _mid " << INT() << endl << " _upper := " << CAST(INT(), "_keys + (_klen << 1) - 2") << endl << " for {" << endl << " if _upper < _lower {" << endl << " break" << endl << " }" << endl << endl << " _mid = _lower + (((_upper - _lower) >> 1) & ^1)" << endl << " switch {" << endl << " case " << GET_WIDE_KEY() << " < " << K() << "[_mid]" << ":" << endl << " _upper = _mid - 2" << endl << " case " << GET_WIDE_KEY() << " > " << K() << "[_mid + 1]" << ":" << endl << " _lower = _mid + 2" << endl << " default:" << endl << " _trans += " << CAST(INT(), "(_mid - " + CAST(INT(), "_keys") + ") >> 1") << endl << " goto _match" << endl << " }" << endl << " }" << endl << " _trans += _klen" << endl << " }" << endl << endl; } void GoTabCodeGen::COND_TRANSLATE() { out << " _widec = " << CAST(WIDE_ALPH_TYPE(), GET_KEY()) << endl << " _klen = " << CAST(INT(), CL() + "[" + vCS() + "]") << endl << " _keys = " << CAST(INT(), CO() + "[" + vCS() + "] * 2") << endl << " if _klen > 0 {" << endl << " _lower := " << CAST(INT(), "_keys") << endl << " var _mid " << INT() << endl << " _upper := " << CAST(INT(), "_keys + (_klen << 1) - 2") << endl << " COND_LOOP:" << endl << " for {" << endl << " if _upper < _lower {" << endl << " break" << endl << " }" << endl << endl << " _mid = _lower + (((_upper - _lower) >> 1) & ^1)" << endl << " switch {" << endl << " case " << GET_WIDE_KEY() << " < " << CAST(WIDE_ALPH_TYPE(), CK() + "[_mid]") << ":" << endl << " _upper = _mid - 2" << endl << " case " << GET_WIDE_KEY() << " > " << CAST(WIDE_ALPH_TYPE(), CK() + "[_mid + 1]") << ":" << endl << " _lower = _mid + 2" << endl << " default:" << endl << " switch " << C() << "[" << CAST(INT(), CO() + "[" + vCS() + "]") << " + ((_mid - _keys)>>1)] {" << endl; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << TABS(4) << "case " << condSpace->condSpaceId << ":" << endl; out << TABS(5) << "_widec = " << KEY(condSpace->baseKey) << " + (" << CAST(WIDE_ALPH_TYPE(), GET_KEY()) << " - " << KEY(keyOps->minKey) << ")" << endl; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(5) << "if "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " {" << endl << TABS(6) << "_widec += " << condValOffset << endl << TABS(5) << "}" << endl; } } out << " }" << endl << " break COND_LOOP" << endl << " }" << endl << " }" << endl << " }" << endl << endl; } void GoTabCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {" << endl << " var _klen " << INT() << endl; if ( redFsm->anyRegCurStateRef() ) out << " var _ps " << INT() << endl; out << " var _trans " << INT() << endl; if ( redFsm->anyConditions() ) out << " var _widec " << WIDE_ALPH_TYPE() << endl; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " var _acts " << INT() << endl << " var _nacts " << UINT() << endl; } out << " var _keys " << INT() << endl; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " == " << PE() << " {" << endl << " goto _test_eof" << endl << " }" << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } out << "_resume:" << endl; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << CAST(INT(), FSA() + "[" + vCS() + "]") << endl << " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl << " for ; _nacts > 0; _nacts-- {" << endl << " _acts++" << endl << " switch " << A() << "[_acts - 1]" << " {" << endl; FROM_STATE_ACTION_SWITCH(2); out << " }" << endl << " }" << endl << endl; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); out << "_match:" << endl; if ( useIndicies ) out << " _trans = " << CAST(INT(), I() + "[_trans]") << endl; if ( redFsm->anyEofTrans() ) out << "_eof_trans:" << endl; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << endl; out << " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl << endl; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] == 0 {" << endl << " goto _again" << endl << " }" << endl << endl << " _acts = " << CAST(INT(), TA() + "[_trans]") << endl << " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl << " for ; _nacts > 0; _nacts-- {" << endl << " _acts++" << endl << " switch " << A() << "[_acts-1]" << " {" << endl; ACTION_SWITCH(2); out << " }" << endl << " }" << endl << endl; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:" << endl; if ( redFsm->anyToStateActions() ) { out << " _acts = " << CAST(INT(), TSA() + "[" + vCS() + "]") << endl << " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl << " for ; _nacts > 0; _nacts-- {" << endl << " _acts++" << endl << " switch " << A() << "[_acts-1] {" << endl; TO_STATE_ACTION_SWITCH(2); out << " }" << endl << " }" << endl << endl; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " == " << redFsm->errState->id << " {" << endl << " goto _out" << endl << " }" << endl; } if ( !noEnd ) { out << " " << P() << "++" << endl << " if " << P() << " != " << PE() << " {" << endl << " goto _resume" << endl << " }" << endl; } else { out << " " << P() << "++" << endl << " goto _resume" << endl; } if ( testEofUsed ) out << " _test_eof: {}" << endl; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << " {" << endl; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0 {" << endl << " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl << " goto _eof_trans" << endl << " }" << endl; } if ( redFsm->anyEofActions() ) { out << " __acts := " << EA() << "[" << vCS() << "]" << endl << " __nacts := " << CAST(UINT(), A() + "[__acts]") << "; __acts++" << endl << " for ; __nacts > 0; __nacts-- {" << endl << " __acts++" << endl << " switch " << A() << "[__acts-1] {" << endl; EOF_ACTION_SWITCH(3); out << " }" << endl << " }" << endl; } out << " }" << endl << endl; } if ( outLabelUsed ) out << " _out: {}" << endl; out << " }" << endl; } ragel-6.10/ragel/cdipgoto.cpp0000664000175000017500000003037113065111230013057 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdipgoto.h" #include "redfsm.h" #include "gendata.h" #include "bstmap.h" bool IpGotoCodeGen::useAgainLabel() { return redFsm->anyActionRets() || redFsm->anyActionByValControl() || redFsm->anyRegNextStmt(); } void IpGotoCodeGen::EOF_CHECK( ostream &ret, int gotoDest ) { ret << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof" << gotoDest << ";\n"; testEofUsed = true; } void IpGotoCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{"; if ( inFinish && !noEnd ) EOF_CHECK( ret, gotoDest ); ret << CTRL_FLOW() << "goto st" << gotoDest << ";"; ret << "}"; } void IpGotoCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << targState << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret, callDest ); ret << CTRL_FLOW() << "goto st" << callDest << ";"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void IpGotoCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << targState << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; if ( inFinish && !noEnd ) FsmCodeGen::EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void IpGotoCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];"; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false, false ); ret << "}"; } if ( inFinish && !noEnd ) FsmCodeGen::EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void IpGotoCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{"; ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; if ( inFinish && !noEnd ) FsmCodeGen::EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void IpGotoCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void IpGotoCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; } void IpGotoCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void IpGotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << targState; } void IpGotoCodeGen::BREAK( ostream &ret, int targState, bool csForced ) { outLabelUsed = true; ret << "{" << P() << "++; "; if ( !csForced ) ret << vCS() << " = " << targState << "; "; ret << CTRL_FLOW() << "goto _out;}"; } bool IpGotoCodeGen::IN_TRANS_ACTIONS( RedStateAp *state ) { bool anyWritten = false; /* Emit any transitions that have actions and that go to this state. */ for ( int it = 0; it < state->numInTrans; it++ ) { RedTransAp *trans = state->inTrans[it]; if ( trans->action != 0 && trans->labelNeeded ) { /* Remember that we wrote an action so we know to write the * line directive for going back to the output. */ anyWritten = true; /* Write the label for the transition so it can be jumped to. */ out << "tr" << trans->id << ":\n"; /* If the action contains a next, then we must preload the current * state since the action may or may not set it. */ if ( trans->action->anyNextStmt() ) out << " " << vCS() << " = " << trans->targ->id << ";\n"; /* Write each action in the list. */ for ( GenActionTable::Iter item = trans->action->key; item.lte(); item++ ) { ACTION( out, item->value, trans->targ->id, false, trans->action->anyNextStmt() ); } /* If the action contains a next then we need to reload, otherwise * jump directly to the target state. */ if ( trans->action->anyNextStmt() ) out << "\tgoto _again;\n"; else out << "\tgoto st" << trans->targ->id << ";\n"; } } return anyWritten; } /* Called from GotoCodeGen::STATE_GOTOS just before writing the gotos for each * state. */ void IpGotoCodeGen::GOTO_HEADER( RedStateAp *state ) { bool anyWritten = IN_TRANS_ACTIONS( state ); if ( state->labelNeeded ) out << "st" << state->id << ":\n"; if ( state->toStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->toStateAction->key; item.lte(); item++ ) { ACTION( out, item->value, state->id, false, state->toStateAction->anyNextStmt() ); } } /* Advance and test buffer pos. */ if ( state->labelNeeded ) { if ( !noEnd ) { out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _test_eof" << state->id << ";\n"; } else { out << " " << P() << " += 1;\n"; } } /* Give the state a switch case. */ out << "case " << state->id << ":\n"; if ( state->fromStateAction != 0 ) { /* Remember that we wrote an action. Write every action in the list. */ anyWritten = true; for ( GenActionTable::Iter item = state->fromStateAction->key; item.lte(); item++ ) { ACTION( out, item->value, state->id, false, state->fromStateAction->anyNextStmt() ); } } if ( anyWritten ) genLineDirective( out ); /* Record the prev state if necessary. */ if ( state->anyRegCurStateRef() ) out << " _ps = " << state->id << ";\n"; } void IpGotoCodeGen::STATE_GOTO_ERROR() { /* In the error state we need to emit some stuff that usually goes into * the header. */ RedStateAp *state = redFsm->errState; bool anyWritten = IN_TRANS_ACTIONS( state ); /* No case label needed since we don't switch on the error state. */ if ( anyWritten ) genLineDirective( out ); if ( state->labelNeeded ) out << "st" << state->id << ":\n"; /* Break out here. */ outLabelUsed = true; out << vCS() << " = " << state->id << ";\n"; out << " goto _out;\n"; } /* Emit the goto to take for a given transition. */ std::ostream &IpGotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { if ( trans->action != 0 ) { /* Go to the transition which will go to the state. */ out << TABS(level) << "goto tr" << trans->id << ";"; } else { /* Go directly to the target state. */ out << TABS(level) << "goto st" << trans->targ->id << ";"; } return out; } std::ostream &IpGotoCodeGen::EXIT_STATES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->outNeeded ) { testEofUsed = true; out << " _test_eof" << st->id << ": " << vCS() << " = " << st->id << "; goto _test_eof; \n"; } } return out; } std::ostream &IpGotoCodeGen::AGAIN_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { out << " case " << st->id << ": goto st" << st->id << ";\n"; } return out; } std::ostream &IpGotoCodeGen::FINISH_CASES() { bool anyWritten = false; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofAction != 0 ) { if ( st->eofAction->eofRefs == 0 ) st->eofAction->eofRefs = new IntSet; st->eofAction->eofRefs->insert( st->id ); } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " case " << st->id << ": goto tr" << st->eofTrans->id << ";\n"; } for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { if ( act->eofRefs != 0 ) { for ( IntSet::Iter pst = *act->eofRefs; pst.lte(); pst++ ) out << " case " << *pst << ": \n"; /* Remember that we wrote a trans so we know to write the * line directive for going back to the output. */ anyWritten = true; /* Write each action in the eof action list. */ for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) ACTION( out, item->value, STATE_ERR_STATE, true, false ); out << "\tbreak;\n"; } } if ( anyWritten ) genLineDirective( out ); return out; } void IpGotoCodeGen::setLabelsNeeded( GenInlineList *inlineList ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Goto: case GenInlineItem::Call: { /* Mark the target as needing a label. */ item->targState->labelNeeded = true; break; } default: break; } if ( item->children != 0 ) setLabelsNeeded( item->children ); } } /* Set up labelNeeded flag for each state. */ void IpGotoCodeGen::setLabelsNeeded() { /* If we use the _again label, then we the _again switch, which uses all * labels. */ if ( useAgainLabel() ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = true; } else { /* Do not use all labels by default, init all labelNeeded vars to false. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) st->labelNeeded = false; /* Walk all transitions and set only those that have targs. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* If there is no action with a next statement, then the label will be * needed. */ if ( trans->action == 0 || !trans->action->anyNextStmt() ) trans->targ->labelNeeded = true; /* Need labels for states that have goto or calls in action code * invoked on characters (ie, not from out action code). */ if ( trans->action != 0 ) { /* Loop the actions. */ for ( GenActionTable::Iter act = trans->action->key; act.lte(); act++ ) { /* Get the action and walk it's tree. */ setLabelsNeeded( act->value->inlineList ); } } } for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofAction != 0 ) { for ( GenActionTable::Iter item = st->eofAction->key; item.lte(); item++ ) setLabelsNeeded( item->value->inlineList ); } } } if ( !noEnd ) { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st != redFsm->errState ) st->outNeeded = st->labelNeeded; } } } void IpGotoCodeGen::writeData() { STATE_IDS(); } void IpGotoCodeGen::writeExec() { /* Must set labels immediately before writing because we may depend on the * noend write option. */ setLabelsNeeded(); testEofUsed = false; outLabelUsed = false; out << " {\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( useAgainLabel() ) { out << " goto _resume;\n" "\n" "_again:\n" " switch ( " << vCS() << " ) {\n"; AGAIN_CASES() << " default: break;\n" " }\n" "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( ++" << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } else { out << " " << P() << " += 1;\n"; } out << "_resume:\n"; } out << " switch ( " << vCS() << " )\n {\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " }\n"; EXIT_STATES() << "\n"; if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n" " switch ( " << vCS() << " ) {\n"; FINISH_CASES(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/rubyftable.cpp0000664000175000017500000002770713065111230013417 00000000000000/* * 2007 Victor Hugo Borja * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "redfsm.h" #include "gendata.h" #include "ragel.h" #include "rubyftable.h" using std::ostream; using std::ostringstream; using std::string; using std::cerr; using std::endl; void RubyFTabCodeGen::GOTO( ostream &out, int gotoDest, bool inFinish ) { out << " begin\n" " " << vCS() << " = " << gotoDest << "\n" " _goto_level = _again\n" " next\n" " end\n"; } void RubyFTabCodeGen::GOTO_EXPR( ostream &out, GenInlineItem *ilItem, bool inFinish ) { out << " begin\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, 0, inFinish ); out << ")\n"; out << " _goto_level = _again\n" " next\n" " end\n"; } void RubyFTabCodeGen::CALL( ostream &out, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << "+= 1\n" " " << vCS() << " = " << callDest << "\n" " _goto_level = _again\n" " next\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyFTabCodeGen::CALL_EXPR(ostream &out, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, prePushExpr, 0, false ); } out << " begin\n" " " << STACK() << "[" << TOP() << "] = " << vCS() << "\n" " " << TOP() << " += 1\n" " " << vCS() << " = ("; INLINE_LIST( out, ilItem->children, targState, inFinish ); out << ")\n"; out << " _goto_level = _again\n" " next\n" " end\n"; if ( prePushExpr != 0 ) out << "end\n"; } void RubyFTabCodeGen::RET( ostream &out, bool inFinish ) { out << " begin\n" " " << TOP() << " -= 1\n" " " << vCS() << " = " << STACK() << "[" << TOP() << "]\n"; if ( postPopExpr != 0 ) { out << "begin\n"; INLINE_LIST( out, postPopExpr, 0, false ); out << "end\n"; } out << " _goto_level = _again\n" " next\n" " end\n"; } void RubyFTabCodeGen::BREAK( ostream &out, int targState ) { out << " begin\n" " " << P() << " += 1\n" " _goto_level = _out\n" " next\n" " end\n"; } std::ostream &RubyFTabCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &RubyFTabCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RubyFTabCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &RubyFTabCodeGen::ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* Write the entry label. */ out << "\twhen " << redAct->actListId+1 << " then\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); } } genLineDirective( out ); return out; } int RubyFTabCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; return act; } int RubyFTabCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; return act; } int RubyFTabCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; return act; } /* Write out the function for a transition. */ int RubyFTabCodeGen::TRANS_ACTION( RedTransAp *trans ) { int action = 0; if ( trans->action != 0 ) action = trans->action->actListId+1; return action; } void RubyFTabCodeGen::writeData() { if ( redFsm->anyConditions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondOffset), CO() ); COND_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondLen), CL() ); COND_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpaceId), C() ); COND_SPACES(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( ARRAY_TYPE(redFsm->maxKeyOffset), KO() ); KEY_OFFSETS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSingleLen), SL() ); SINGLE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxRangeLen), RL() ); RANGE_LENS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset), IO() ); INDEX_OFFSETS(); CLOSE_ARRAY() << "\n"; if ( useIndicies ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS_WI(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS_WI(); CLOSE_ARRAY() << "\n"; } } else { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void RubyFTabCodeGen::writeExec() { out << "begin\n" " testEof = false\n" " _klen, _trans, _keys"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; if ( redFsm->anyConditions() ) out << ", _widec"; out << " = nil\n"; out << " _goto_level = 0\n" " _resume = 10\n" " _eof_trans = 15\n" " _again = 20\n" " _test_eof = 30\n" " _out = 40\n"; out << " while true\n" " if _goto_level <= 0\n"; if ( !noEnd ) { out << " if " << P() << " == " << PE() << "\n" " _goto_level = _test_eof\n" " next\n" " end\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } /* The resume label. */ out << " end\n" " if _goto_level <= _resume\n"; if ( redFsm->anyFromStateActions() ) { out << " case " << FSA() << "[" << vCS() << "] \n"; FROM_STATE_ACTION_SWITCH() << " end # from state action switch \n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( useIndicies ) out << " _trans = " << I() << "[_trans];\n"; if ( redFsm->anyEofTrans() ) { out << " end\n" " if _goto_level <= _eof_trans\n"; } if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if " << TA() << "[_trans] != 0\n" "\n" " case " << TA() << "[_trans] \n"; ACTION_SWITCH() << " end # action switch \n" " end\n" "\n"; } /* The again label. */ out << " end\n" " if _goto_level <= _again\n"; if ( redFsm->anyToStateActions() ) { out << " case " << TSA() << "[" << vCS() << "] \n"; TO_STATE_ACTION_SWITCH() << " end\n" "\n"; } if ( redFsm->errState != 0 ) { out << " if " << vCS() << " == " << redFsm->errState->id << "\n" " _goto_level = _out\n" " next\n" " end\n"; } out << " " << P() << " += 1\n"; if ( !noEnd ) { out << " if " << P() << " != " << PE() << "\n" " _goto_level = _resume\n" " next\n" " end\n"; } else { out << " _goto_level = _resume\n" " next\n"; } /* The test eof label. */ out << " end\n" " if _goto_level <= _test_eof\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " == " << vEOF() << "\n"; if ( redFsm->anyEofTrans() ) { out << " if " << ET() << "[" << vCS() << "] > 0\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " _goto_level = _eof_trans\n" " next;\n" " end\n"; } if ( redFsm->anyEofActions() ) { out << " begin\n" " case ( " << EA() << "[" << vCS() << "] )\n"; EOF_ACTION_SWITCH() << " end\n" " end\n"; } out << " end\n" "\n"; } out << " end\n" " if _goto_level <= _out\n" " break\n" " end\n" "end\n"; /* Wrapping the execute block. */ out << " end\n"; } void RubyFTabCodeGen::calcIndexSize() { int sizeWithInds = 0, sizeWithoutInds = 0; /* Calculate cost of using with indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithInds += arrayTypeSize(redFsm->maxIndex) * totalIndex; } sizeWithInds += arrayTypeSize(redFsm->maxState) * redFsm->transSet.length(); if ( redFsm->anyActions() ) sizeWithInds += arrayTypeSize(redFsm->maxActListId) * redFsm->transSet.length(); /* Calculate the cost of not using indicies. */ for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { int totalIndex = st->outSingle.length() + st->outRange.length() + (st->defTrans == 0 ? 0 : 1); sizeWithoutInds += arrayTypeSize(redFsm->maxState) * totalIndex; if ( redFsm->anyActions() ) sizeWithoutInds += arrayTypeSize(redFsm->maxActListId) * totalIndex; } /* If using indicies reduces the size, use them. */ useIndicies = sizeWithInds < sizeWithoutInds; } /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/cscodegen.h0000664000175000017500000001530013065111230012641 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CSCODEGEN_H #define _CSCODEGEN_H #include #include #include #include "common.h" #include "gendata.h" using std::string; using std::ostream; /* Integer array line length. */ #define IALL 8 /* Forwards. */ struct RedFsmAp; struct RedStateAp; struct CodeGenData; struct GenAction; struct NameInst; struct GenInlineItem; struct GenInlineList; struct RedAction; struct LongestMatch; struct LongestMatchPart; string itoa( int i ); /* * class CSharpFsmCodeGen */ class CSharpFsmCodeGen : public CodeGenData { public: CSharpFsmCodeGen( ostream &out ); virtual ~CSharpFsmCodeGen() {} virtual void finishRagelDef(); virtual void writeInit(); virtual void writeStart(); virtual void writeFirstFinal(); virtual void writeError(); protected: string FSM_NAME(); string START_STATE_ID(); ostream &ACTIONS_ARRAY(); string GET_WIDE_KEY(); string GET_WIDE_KEY( RedStateAp *state ); string TABS( int level ); string KEY( Key key ); string ALPHA_KEY( Key key ); string LDIR_PATH( char *path ); void ACTION( ostream &ret, GenAction *action, int targState, bool inFinish ); void CONDITION( ostream &ret, GenAction *condition ); string ALPH_TYPE(); string WIDE_ALPH_TYPE(); string ARRAY_TYPE( unsigned long maxVal ); string ARRAY_TYPE( unsigned long maxVal, bool forceSigned ); virtual string ARR_OFF( string ptr, string offset ) = 0; virtual string CAST( string type ) = 0; virtual string UINT() = 0; virtual string NULL_ITEM() = 0; virtual string POINTER() = 0; virtual string GET_KEY(); virtual ostream &SWITCH_DEFAULT() = 0; string P(); string PE(); string vEOF(); string ACCESS(); string vCS(); string STACK(); string TOP(); string TOKSTART(); string TOKEND(); string ACT(); string DATA_PREFIX(); string PM() { return "_" + DATA_PREFIX() + "partition_map"; } string C() { return "_" + DATA_PREFIX() + "cond_spaces"; } string CK() { return "_" + DATA_PREFIX() + "cond_keys"; } string K() { return "_" + DATA_PREFIX() + "trans_keys"; } string I() { return "_" + DATA_PREFIX() + "indicies"; } string CO() { return "_" + DATA_PREFIX() + "cond_offsets"; } string KO() { return "_" + DATA_PREFIX() + "key_offsets"; } string IO() { return "_" + DATA_PREFIX() + "index_offsets"; } string CL() { return "_" + DATA_PREFIX() + "cond_lengths"; } string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } string ET() { return "_" + DATA_PREFIX() + "eof_trans"; } string SP() { return "_" + DATA_PREFIX() + "key_spans"; } string CSP() { return "_" + DATA_PREFIX() + "cond_key_spans"; } string START() { return DATA_PREFIX() + "start"; } string ERROR() { return DATA_PREFIX() + "error"; } string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; } string CTXDATA() { return DATA_PREFIX() + "ctxdata"; } void INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish ); virtual void GOTO( ostream &ret, int gotoDest, bool inFinish ) = 0; virtual void CALL( ostream &ret, int callDest, int targState, bool inFinish ) = 0; virtual void NEXT( ostream &ret, int nextDest, bool inFinish ) = 0; virtual void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; virtual void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) = 0; virtual void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) = 0; virtual void RET( ostream &ret, bool inFinish ) = 0; virtual void BREAK( ostream &ret, int targState ) = 0; virtual void CURS( ostream &ret, bool inFinish ) = 0; virtual void TARGS( ostream &ret, bool inFinish, int targState ) = 0; void EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void SET_ACT( ostream &ret, GenInlineItem *item ); void INIT_TOKSTART( ostream &ret, GenInlineItem *item ); void INIT_ACT( ostream &ret, GenInlineItem *item ); void SET_TOKSTART( ostream &ret, GenInlineItem *item ); void SET_TOKEND( ostream &ret, GenInlineItem *item ); void GET_TOKEND( ostream &ret, GenInlineItem *item ); void SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish ); void STATE_IDS(); string ERROR_STATE(); string FIRST_FINAL_STATE(); virtual string PTR_CONST() = 0; virtual ostream &OPEN_ARRAY( string type, string name ) = 0; virtual ostream &CLOSE_ARRAY() = 0; virtual ostream &STATIC_VAR( string type, string name ) = 0; virtual string CTRL_FLOW() = 0; ostream &source_warning(const InputLoc &loc); ostream &source_error(const InputLoc &loc); unsigned int arrayTypeSize( unsigned long maxVal ); bool outLabelUsed; bool testEofUsed; bool againLabelUsed; bool useIndicies; public: /* Determine if we should use indicies. */ virtual void calcIndexSize() {} void genLineDirective( ostream &out ); }; class CSharpCodeGen : virtual public CSharpFsmCodeGen { public: CSharpCodeGen( ostream &out ) : CSharpFsmCodeGen(out) {} virtual string GET_KEY(); virtual string NULL_ITEM(); virtual string POINTER(); virtual ostream &SWITCH_DEFAULT(); virtual ostream &OPEN_ARRAY( string type, string name ); virtual ostream &CLOSE_ARRAY(); virtual ostream &STATIC_VAR( string type, string name ); virtual string ARR_OFF( string ptr, string offset ); virtual string CAST( string type ); virtual string UINT(); virtual string PTR_CONST(); virtual string CTRL_FLOW(); virtual void writeExports(); }; #define MAX(a, b) (a > b ? a : b) #endif ragel-6.10/ragel/fsmstate.cpp0000664000175000017500000003146213065111230013077 00000000000000/* * Copyright 2002 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "fsmgraph.h" #include using namespace std; /* Construct a mark index for a specified number of states. Must new up * an array that is states^2 in size. */ MarkIndex::MarkIndex( int states ) : numStates(states) { /* Total pairs is states^2. Actually only use half of these, but we allocate * them all to make indexing into the array easier. */ int total = states * states; /* New up chars so that individual DListEl constructors are * not called. Zero out the mem manually. */ array = new bool[total]; memset( array, 0, sizeof(bool) * total ); } /* Free the array used to store state pairs. */ MarkIndex::~MarkIndex() { delete[] array; } /* Mark a pair of states. States are specified by their number. The * marked states are moved from the unmarked list to the marked list. */ void MarkIndex::markPair(int state1, int state2) { int pos = ( state1 >= state2 ) ? ( state1 * numStates ) + state2 : ( state2 * numStates ) + state1; array[pos] = true; } /* Returns true if the pair of states are marked. Returns false otherwise. * Ordering of states given does not matter. */ bool MarkIndex::isPairMarked(int state1, int state2) { int pos = ( state1 >= state2 ) ? ( state1 * numStates ) + state2 : ( state2 * numStates ) + state1; return array[pos]; } /* Create a new fsm state. State has not out transitions or in transitions, not * out out transition data and not number. */ StateAp::StateAp() : /* No out or in transitions. */ outList(), inList(), /* No EOF target. */ eofTarget(0), /* No entry points, or epsilon trans. */ entryIds(), epsilonTrans(), /* Conditions. */ stateCondList(), /* No transitions in from other states. */ foreignInTrans(0), /* Only used during merging. Normally null. */ stateDictEl(0), eptVect(0), /* No state identification bits. */ stateBits(0), /* No Priority data. */ outPriorTable(), /* No Action data. */ toStateActionTable(), fromStateActionTable(), outActionTable(), outCondSet(), errActionTable(), eofActionTable() { } /* Copy everything except actual the transitions. That is left up to the * FsmAp copy constructor. */ StateAp::StateAp(const StateAp &other) : /* All lists are cleared. They will be filled in when the * individual transitions are duplicated and attached. */ outList(), inList(), /* Set this using the original state's eofTarget. It will get mapped back * to the new machine in the Fsm copy constructor. */ eofTarget(other.eofTarget), /* Duplicate the entry id set and epsilon transitions. These * are sets of integers and as such need no fixing. */ entryIds(other.entryIds), epsilonTrans(other.epsilonTrans), /* Copy in the elements of the conditions. */ stateCondList( other.stateCondList ), /* No transitions in from other states. */ foreignInTrans(0), /* This is only used during merging. Normally null. */ stateDictEl(0), eptVect(0), /* Fsm state data. */ stateBits(other.stateBits), /* Copy in priority data. */ outPriorTable(other.outPriorTable), /* Copy in action data. */ toStateActionTable(other.toStateActionTable), fromStateActionTable(other.fromStateActionTable), outActionTable(other.outActionTable), outCondSet(other.outCondSet), errActionTable(other.errActionTable), eofActionTable(other.eofActionTable) { /* Duplicate all the transitions. */ for ( TransList::Iter trans = other.outList; trans.lte(); trans++ ) { /* Dupicate and store the orginal target in the transition. This will * be corrected once all the states have been created. */ TransAp *newTrans = new TransAp(*trans); assert( trans->lmActionTable.length() == 0 ); newTrans->toState = trans->toState; outList.append( newTrans ); } } /* If there is a state dict element, then delete it. Everything else is left * up to the FsmGraph destructor. */ StateAp::~StateAp() { if ( stateDictEl != 0 ) delete stateDictEl; } /* Compare two states using pointers to the states. With the approximate * compare, the idea is that if the compare finds them the same, they can * immediately be merged. */ int ApproxCompare::compare( const StateAp *state1, const StateAp *state2 ) { int compareRes; /* Test final state status. */ if ( (state1->stateBits & STB_ISFINAL) && !(state2->stateBits & STB_ISFINAL) ) return -1; else if ( !(state1->stateBits & STB_ISFINAL) && (state2->stateBits & STB_ISFINAL) ) return 1; /* Test epsilon transition sets. */ compareRes = CmpEpsilonTrans::compare( state1->epsilonTrans, state2->epsilonTrans ); if ( compareRes != 0 ) return compareRes; /* Compare the out transitions. */ compareRes = FsmAp::compareStateData( state1, state2 ); if ( compareRes != 0 ) return compareRes; /* Use a pair iterator to get the transition pairs. */ PairIter outPair( state1->outList.head, state2->outList.head ); for ( ; !outPair.end(); outPair++ ) { switch ( outPair.userState ) { case RangeInS1: compareRes = FsmAp::compareFullPtr( outPair.s1Tel.trans, 0 ); if ( compareRes != 0 ) return compareRes; break; case RangeInS2: compareRes = FsmAp::compareFullPtr( 0, outPair.s2Tel.trans ); if ( compareRes != 0 ) return compareRes; break; case RangeOverlap: compareRes = FsmAp::compareFullPtr( outPair.s1Tel.trans, outPair.s2Tel.trans ); if ( compareRes != 0 ) return compareRes; break; case BreakS1: case BreakS2: break; } } /* Check EOF targets. */ if ( state1->eofTarget < state2->eofTarget ) return -1; else if ( state1->eofTarget > state2->eofTarget ) return 1; /* Got through the entire state comparison, deem them equal. */ return 0; } /* Compare class used in the initial partition. */ int InitPartitionCompare::compare( const StateAp *state1 , const StateAp *state2 ) { int compareRes; /* Test final state status. */ if ( (state1->stateBits & STB_ISFINAL) && !(state2->stateBits & STB_ISFINAL) ) return -1; else if ( !(state1->stateBits & STB_ISFINAL) && (state2->stateBits & STB_ISFINAL) ) return 1; /* Test epsilon transition sets. */ compareRes = CmpEpsilonTrans::compare( state1->epsilonTrans, state2->epsilonTrans ); if ( compareRes != 0 ) return compareRes; /* Compare the out transitions. */ compareRes = FsmAp::compareStateData( state1, state2 ); if ( compareRes != 0 ) return compareRes; /* Use a pair iterator to test the condition pairs. */ PairIter condPair( state1->stateCondList.head, state2->stateCondList.head ); for ( ; !condPair.end(); condPair++ ) { switch ( condPair.userState ) { case RangeInS1: return 1; case RangeInS2: return -1; case RangeOverlap: { CondSpace *condSpace1 = condPair.s1Tel.trans->condSpace; CondSpace *condSpace2 = condPair.s2Tel.trans->condSpace; if ( condSpace1 < condSpace2 ) return -1; else if ( condSpace1 > condSpace2 ) return 1; break; } case BreakS1: case BreakS2: break; } } /* Use a pair iterator to test the transition pairs. */ PairIter outPair( state1->outList.head, state2->outList.head ); for ( ; !outPair.end(); outPair++ ) { switch ( outPair.userState ) { case RangeInS1: compareRes = FsmAp::compareDataPtr( outPair.s1Tel.trans, 0 ); if ( compareRes != 0 ) return compareRes; break; case RangeInS2: compareRes = FsmAp::compareDataPtr( 0, outPair.s2Tel.trans ); if ( compareRes != 0 ) return compareRes; break; case RangeOverlap: compareRes = FsmAp::compareDataPtr( outPair.s1Tel.trans, outPair.s2Tel.trans ); if ( compareRes != 0 ) return compareRes; break; case BreakS1: case BreakS2: break; } } return 0; } /* Compare class for the sort that does the partitioning. */ int PartitionCompare::compare( const StateAp *state1, const StateAp *state2 ) { int compareRes; /* Use a pair iterator to get the transition pairs. */ PairIter outPair( state1->outList.head, state2->outList.head ); for ( ; !outPair.end(); outPair++ ) { switch ( outPair.userState ) { case RangeInS1: compareRes = FsmAp::comparePartPtr( outPair.s1Tel.trans, 0 ); if ( compareRes != 0 ) return compareRes; break; case RangeInS2: compareRes = FsmAp::comparePartPtr( 0, outPair.s2Tel.trans ); if ( compareRes != 0 ) return compareRes; break; case RangeOverlap: compareRes = FsmAp::comparePartPtr( outPair.s1Tel.trans, outPair.s2Tel.trans ); if ( compareRes != 0 ) return compareRes; break; case BreakS1: case BreakS2: break; } } /* Test eof targets. */ if ( state1->eofTarget == 0 && state2->eofTarget != 0 ) return -1; else if ( state1->eofTarget != 0 && state2->eofTarget == 0 ) return 1; else if ( state1->eofTarget != 0 ) { /* Both eof targets are set. */ compareRes = CmpOrd< MinPartition* >::compare( state1->eofTarget->alg.partition, state2->eofTarget->alg.partition ); if ( compareRes != 0 ) return compareRes; } return 0; } /* Compare class for the sort that does the partitioning. */ bool MarkCompare::shouldMark( MarkIndex &markIndex, const StateAp *state1, const StateAp *state2 ) { /* Use a pair iterator to get the transition pairs. */ PairIter outPair( state1->outList.head, state2->outList.head ); for ( ; !outPair.end(); outPair++ ) { switch ( outPair.userState ) { case RangeInS1: if ( FsmAp::shouldMarkPtr( markIndex, outPair.s1Tel.trans, 0 ) ) return true; break; case RangeInS2: if ( FsmAp::shouldMarkPtr( markIndex, 0, outPair.s2Tel.trans ) ) return true; break; case RangeOverlap: if ( FsmAp::shouldMarkPtr( markIndex, outPair.s1Tel.trans, outPair.s2Tel.trans ) ) return true; break; case BreakS1: case BreakS2: break; } } return false; } /* * Transition Comparison. */ /* Compare target partitions. Either pointer may be null. */ int FsmAp::comparePartPtr( TransAp *trans1, TransAp *trans2 ) { if ( trans1 != 0 ) { /* If trans1 is set then so should trans2. The initial partitioning * guarantees this for us. */ if ( trans1->toState == 0 && trans2->toState != 0 ) return -1; else if ( trans1->toState != 0 && trans2->toState == 0 ) return 1; else if ( trans1->toState != 0 ) { /* Both of targets are set. */ return CmpOrd< MinPartition* >::compare( trans1->toState->alg.partition, trans2->toState->alg.partition ); } } return 0; } /* Compares two transition pointers according to priority and functions. * Either pointer may be null. Does not consider to state or from state. */ int FsmAp::compareDataPtr( TransAp *trans1, TransAp *trans2 ) { if ( trans1 == 0 && trans2 != 0 ) return -1; else if ( trans1 != 0 && trans2 == 0 ) return 1; else if ( trans1 != 0 ) { /* Both of the transition pointers are set. */ int compareRes = compareTransData( trans1, trans2 ); if ( compareRes != 0 ) return compareRes; } return 0; } /* Compares two transitions according to target state, priority and functions. * Does not consider from state. Either of the pointers may be null. */ int FsmAp::compareFullPtr( TransAp *trans1, TransAp *trans2 ) { if ( (trans1 != 0) ^ (trans2 != 0) ) { /* Exactly one of the transitions is set. */ if ( trans1 != 0 ) return -1; else return 1; } else if ( trans1 != 0 ) { /* Both of the transition pointers are set. Test target state, * priority and funcs. */ if ( trans1->toState < trans2->toState ) return -1; else if ( trans1->toState > trans2->toState ) return 1; else if ( trans1->toState != 0 ) { /* Test transition data. */ int compareRes = compareTransData( trans1, trans2 ); if ( compareRes != 0 ) return compareRes; } } return 0; } bool FsmAp::shouldMarkPtr( MarkIndex &markIndex, TransAp *trans1, TransAp *trans2 ) { if ( (trans1 != 0) ^ (trans2 != 0) ) { /* Exactly one of the transitions is set. The initial mark round * should rule out this case. */ assert( false ); } else if ( trans1 != 0 ) { /* Both of the transitions are set. If the target pair is marked, then * the pair we are considering gets marked. */ return markIndex.isPairMarked( trans1->toState->alg.stateNum, trans2->toState->alg.stateNum ); } /* Neither of the transitiosn are set. */ return false; } ragel-6.10/ragel/fsmgraph.cpp0000664000175000017500000013121413065111230013054 00000000000000/* * Copyright 2001, 2002, 2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "fsmgraph.h" #include "mergesort.h" #include "parsedata.h" using std::cerr; using std::endl; /* Make a new state. The new state will be put on the graph's * list of state. The new state can be created final or non final. */ StateAp *FsmAp::addState() { /* Make the new state to return. */ StateAp *state = new StateAp(); if ( misfitAccounting ) { /* Create the new state on the misfit list. All states are created * with no foreign in transitions. */ misfitList.append( state ); } else { /* Create the new state. */ stateList.append( state ); } return state; } /* Construct an FSM that is the concatenation of an array of characters. A new * machine will be made that has len+1 states with one transition between each * state for each integer in str. IsSigned determines if the integers are to * be considered as signed or unsigned ints. */ void FsmAp::concatFsm( Key *str, int len ) { /* Make the first state and set it as the start state. */ StateAp *last = addState(); setStartState( last ); /* Attach subsequent states. */ for ( int i = 0; i < len; i++ ) { StateAp *newState = addState(); attachNewTrans( last, newState, str[i], str[i] ); last = newState; } /* Make the last state the final state. */ setFinState( last ); } /* Case insensitive version of concatFsm. */ void FsmAp::concatFsmCI( Key *str, int len ) { /* Make the first state and set it as the start state. */ StateAp *last = addState(); setStartState( last ); /* Attach subsequent states. */ for ( int i = 0; i < len; i++ ) { StateAp *newState = addState(); KeySet keySet; if ( str[i].isLower() ) keySet.insert( str[i].toUpper() ); if ( str[i].isUpper() ) keySet.insert( str[i].toLower() ); keySet.insert( str[i] ); for ( int i = 0; i < keySet.length(); i++ ) attachNewTrans( last, newState, keySet[i], keySet[i] ); last = newState; } /* Make the last state the final state. */ setFinState( last ); } /* Construct a machine that matches one character. A new machine will be made * that has two states with a single transition between the states. IsSigned * determines if the integers are to be considered as signed or unsigned ints. */ void FsmAp::concatFsm( Key chr ) { /* Two states first start, second final. */ setStartState( addState() ); StateAp *end = addState(); setFinState( end ); /* Attach on the character. */ attachNewTrans( startState, end, chr, chr ); } /* Construct a machine that matches any character in set. A new machine will * be made that has two states and len transitions between the them. The set * should be ordered correctly accroding to KeyOps and should not contain * any duplicates. */ void FsmAp::orFsm( Key *set, int len ) { /* Two states first start, second final. */ setStartState( addState() ); StateAp *end = addState(); setFinState( end ); for ( int i = 1; i < len; i++ ) assert( set[i-1] < set[i] ); /* Attach on all the integers in the given string of ints. */ for ( int i = 0; i < len; i++ ) attachNewTrans( startState, end, set[i], set[i] ); } /* Construct a machine that matches a range of characters. A new machine will * be made with two states and a range transition between them. The range will * match any characters from low to high inclusive. Low should be less than or * equal to high otherwise undefined behaviour results. IsSigned determines * if the integers are to be considered as signed or unsigned ints. */ void FsmAp::rangeFsm( Key low, Key high ) { /* Two states first start, second final. */ setStartState( addState() ); StateAp *end = addState(); setFinState( end ); /* Attach using the range of characters. */ attachNewTrans( startState, end, low, high ); } /* Construct a machine that a repeated range of characters. */ void FsmAp::rangeStarFsm( Key low, Key high) { /* One state which is final and is the start state. */ setStartState( addState() ); setFinState( startState ); /* Attach start to start using range of characters. */ attachNewTrans( startState, startState, low, high ); } /* Construct a machine that matches the empty string. A new machine will be * made with only one state. The new state will be both a start and final * state. IsSigned determines if the machine has a signed or unsigned * alphabet. Fsm operations must be done on machines with the same alphabet * signedness. */ void FsmAp::lambdaFsm( ) { /* Give it one state with no transitions making it * the start state and final state. */ setStartState( addState() ); setFinState( startState ); } /* Construct a machine that matches nothing at all. A new machine will be * made with only one state. It will not be final. */ void FsmAp::emptyFsm( ) { /* Give it one state with no transitions making it * the start state and final state. */ setStartState( addState() ); } void FsmAp::transferOutData( StateAp *destState, StateAp *srcState ) { for ( TransList::Iter trans = destState->outList; trans.lte(); trans++ ) { if ( trans->toState != 0 ) { /* Get the actions data from the outActionTable. */ trans->actionTable.setActions( srcState->outActionTable ); /* Get the priorities from the outPriorTable. */ trans->priorTable.setPriors( srcState->outPriorTable ); } } } /* Kleene star operator. Makes this machine the kleene star of itself. Any * transitions made going out of the machine and back into itself will be * notified that they are leaving transitions by having the leavingFromState * callback invoked. */ void FsmAp::starOp( ) { /* For the merging process. */ MergeData md; /* Turn on misfit accounting to possibly catch the old start state. */ setMisfitAccounting( true ); /* Create the new new start state. It will be set final after the merging * of the final states with the start state is complete. */ StateAp *prevStartState = startState; unsetStartState(); setStartState( addState() ); /* Merge the new start state with the old one to isolate it. */ mergeStates( md, startState, prevStartState ); /* Merge the start state into all final states. Except the start state on * the first pass. If the start state is set final we will be doubling up * its transitions, which will get transfered to any final states that * follow it in the final state set. This will be determined by the order * of items in the final state set. To prevent this we just merge with the * start on a second pass. */ for ( StateSet::Iter st = finStateSet; st.lte(); st++ ) { if ( *st != startState ) mergeStatesLeaving( md, *st, startState ); } /* Now it is safe to merge the start state with itself (provided it * is set final). */ if ( startState->isFinState() ) mergeStatesLeaving( md, startState, startState ); /* Now ensure the new start state is a final state. */ setFinState( startState ); /* Fill in any states that were newed up as combinations of others. */ fillInStates( md ); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } void FsmAp::repeatOp( int times ) { /* Must be 1 and up. 0 produces null machine and requires deleting this. */ assert( times > 0 ); /* A repeat of one does absolutely nothing. */ if ( times == 1 ) return; /* Make a machine to make copies from. */ FsmAp *copyFrom = new FsmAp( *this ); /* Concatentate duplicates onto the end up until before the last. */ for ( int i = 1; i < times-1; i++ ) { FsmAp *dup = new FsmAp( *copyFrom ); doConcat( dup, 0, false ); } /* Now use the copyFrom on the end. */ doConcat( copyFrom, 0, false ); } void FsmAp::optionalRepeatOp( int times ) { /* Must be 1 and up. 0 produces null machine and requires deleting this. */ assert( times > 0 ); /* A repeat of one optional merely allows zero string. */ if ( times == 1 ) { setFinState( startState ); return; } /* Make a machine to make copies from. */ FsmAp *copyFrom = new FsmAp( *this ); /* The state set used in the from end of the concatentation. Starts with * the initial final state set, then after each concatenation, gets set to * the the final states that come from the the duplicate. */ StateSet lastFinSet( finStateSet ); /* Set the initial state to zero to allow zero copies. */ setFinState( startState ); /* Concatentate duplicates onto the end up until before the last. */ for ( int i = 1; i < times-1; i++ ) { /* Make a duplicate for concating and set the fin bits to graph 2 so we * can pick out it's final states after the optional style concat. */ FsmAp *dup = new FsmAp( *copyFrom ); dup->setFinBits( STB_GRAPH2 ); doConcat( dup, &lastFinSet, true ); /* Clear the last final state set and make the new one by taking only * the final states that come from graph 2.*/ lastFinSet.empty(); for ( int i = 0; i < finStateSet.length(); i++ ) { /* If the state came from graph 2, add it to the last set and clear * the bits. */ StateAp *fs = finStateSet[i]; if ( fs->stateBits & STB_GRAPH2 ) { lastFinSet.insert( fs ); fs->stateBits &= ~STB_GRAPH2; } } } /* Now use the copyFrom on the end, no bits set, no bits to clear. */ doConcat( copyFrom, &lastFinSet, true ); } /* Fsm concatentation worker. Supports treating the concatentation as optional, * which essentially leaves the final states of machine one as final. */ void FsmAp::doConcat( FsmAp *other, StateSet *fromStates, bool optional ) { /* For the merging process. */ StateSet finStateSetCopy, startStateSet; MergeData md; /* Turn on misfit accounting for both graphs. */ setMisfitAccounting( true ); other->setMisfitAccounting( true ); /* Get the other's start state. */ StateAp *otherStartState = other->startState; /* Unset other's start state before bringing in the entry points. */ other->unsetStartState(); /* Bring in the rest of other's entry points. */ copyInEntryPoints( other ); other->entryPoints.empty(); /* Bring in other's states into our state lists. */ stateList.append( other->stateList ); misfitList.append( other->misfitList ); /* If from states is not set, then get a copy of our final state set before * we clobber it and use it instead. */ if ( fromStates == 0 ) { finStateSetCopy = finStateSet; fromStates = &finStateSetCopy; } /* Unset all of our final states and get the final states from other. */ if ( !optional ) unsetAllFinStates(); finStateSet.insert( other->finStateSet ); /* Since other's lists are empty, we can delete the fsm without * affecting any states. */ delete other; /* Merge our former final states with the start state of other. */ for ( int i = 0; i < fromStates->length(); i++ ) { StateAp *state = fromStates->data[i]; /* Merge the former final state with other's start state. */ mergeStatesLeaving( md, state, otherStartState ); /* If the former final state was not reset final then we must clear * the state's out trans data. If it got reset final then it gets to * keep its out trans data. This must be done before fillInStates gets * called to prevent the data from being sourced. */ if ( ! state->isFinState() ) clearOutData( state ); } /* Fill in any new states made from merging. */ fillInStates( md ); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } /* Concatenates other to the end of this machine. Other is deleted. Any * transitions made leaving this machine and entering into other are notified * that they are leaving transitions by having the leavingFromState callback * invoked. */ void FsmAp::concatOp( FsmAp *other ) { /* Assert same signedness and return graph concatenation op. */ doConcat( other, 0, false ); } void FsmAp::doOr( FsmAp *other ) { /* For the merging process. */ MergeData md; /* Build a state set consisting of both start states */ StateSet startStateSet; startStateSet.insert( startState ); startStateSet.insert( other->startState ); /* Both of the original start states loose their start state status. */ unsetStartState(); other->unsetStartState(); /* Bring in the rest of other's entry points. */ copyInEntryPoints( other ); other->entryPoints.empty(); /* Merge the lists. This will move all the states from other * into this. No states will be deleted. */ stateList.append( other->stateList ); misfitList.append( other->misfitList ); /* Move the final set data from other into this. */ finStateSet.insert(other->finStateSet); other->finStateSet.empty(); /* Since other's list is empty, we can delete the fsm without * affecting any states. */ delete other; /* Create a new start state. */ setStartState( addState() ); /* Merge the start states. */ mergeStates( md, startState, startStateSet.data, startStateSet.length() ); /* Fill in any new states made from merging. */ fillInStates( md ); } /* Unions other with this machine. Other is deleted. */ void FsmAp::unionOp( FsmAp *other ) { /* Turn on misfit accounting for both graphs. */ setMisfitAccounting( true ); other->setMisfitAccounting( true ); /* Call Worker routine. */ doOr( other ); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } /* Intersects other with this machine. Other is deleted. */ void FsmAp::intersectOp( FsmAp *other ) { /* Turn on misfit accounting for both graphs. */ setMisfitAccounting( true ); other->setMisfitAccounting( true ); /* Set the fin bits on this and other to want each other. */ setFinBits( STB_GRAPH1 ); other->setFinBits( STB_GRAPH2 ); /* Call worker Or routine. */ doOr( other ); /* Unset any final states that are no longer to * be final due to final bits. */ unsetIncompleteFinals(); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); /* Remove states that have no path to a final state. */ removeDeadEndStates(); } /* Set subtracts other machine from this machine. Other is deleted. */ void FsmAp::subtractOp( FsmAp *other ) { /* Turn on misfit accounting for both graphs. */ setMisfitAccounting( true ); other->setMisfitAccounting( true ); /* Set the fin bits of other to be killers. */ other->setFinBits( STB_GRAPH1 ); /* Call worker Or routine. */ doOr( other ); /* Unset any final states that are no longer to * be final due to final bits. */ unsetKilledFinals(); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); /* Remove states that have no path to a final state. */ removeDeadEndStates(); } bool FsmAp::inEptVect( EptVect *eptVect, StateAp *state ) { if ( eptVect != 0 ) { /* Vect is there, walk it looking for state. */ for ( int i = 0; i < eptVect->length(); i++ ) { if ( eptVect->data[i].targ == state ) return true; } } return false; } /* Fill epsilon vectors in a root state from a given starting point. Epmploys * a depth first search through the graph of epsilon transitions. */ void FsmAp::epsilonFillEptVectFrom( StateAp *root, StateAp *from, bool parentLeaving ) { /* Walk the epsilon transitions out of the state. */ for ( EpsilonTrans::Iter ep = from->epsilonTrans; ep.lte(); ep++ ) { /* Find the entry point, if the it does not resove, ignore it. */ EntryMapEl *enLow, *enHigh; if ( entryPoints.findMulti( *ep, enLow, enHigh ) ) { /* Loop the targets. */ for ( EntryMapEl *en = enLow; en <= enHigh; en++ ) { /* Do not add the root or states already in eptVect. */ StateAp *targ = en->value; if ( targ != from && !inEptVect(root->eptVect, targ) ) { /* Maybe need to create the eptVect. */ if ( root->eptVect == 0 ) root->eptVect = new EptVect(); /* If moving to a different graph or if any parent is * leaving then we are leaving. */ bool leaving = parentLeaving || root->owningGraph != targ->owningGraph; /* All ok, add the target epsilon and recurse. */ root->eptVect->append( EptVectEl(targ, leaving) ); epsilonFillEptVectFrom( root, targ, leaving ); } } } } } void FsmAp::shadowReadWriteStates( MergeData &md ) { /* Init isolatedShadow algorithm data. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) st->isolatedShadow = 0; /* Any states that may be both read from and written to must * be shadowed. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) { /* Find such states by looping through stateVect lists, which give us * the states that will be read from. May cause us to visit the states * that we are interested in more than once. */ if ( st->eptVect != 0 ) { /* For all states that will be read from. */ for ( EptVect::Iter ept = *st->eptVect; ept.lte(); ept++ ) { /* Check for read and write to the same state. */ StateAp *targ = ept->targ; if ( targ->eptVect != 0 ) { /* State is to be written to, if the shadow is not already * there, create it. */ if ( targ->isolatedShadow == 0 ) { StateAp *shadow = addState(); mergeStates( md, shadow, targ ); targ->isolatedShadow = shadow; } /* Write shadow into the state vector so that it is the * state that the epsilon transition will read from. */ ept->targ = targ->isolatedShadow; } } } } } void FsmAp::resolveEpsilonTrans( MergeData &md ) { /* Walk the state list and invoke recursive worker on each state. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) epsilonFillEptVectFrom( st, st, false ); /* Prevent reading from and writing to of the same state. */ shadowReadWriteStates( md ); /* For all states that have epsilon transitions out, draw the transitions, * clear the epsilon transitions. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) { /* If there is a state vector, then create the pre-merge state. */ if ( st->eptVect != 0 ) { /* Merge all the epsilon targets into the state. */ for ( EptVect::Iter ept = *st->eptVect; ept.lte(); ept++ ) { if ( ept->leaving ) mergeStatesLeaving( md, st, ept->targ ); else mergeStates( md, st, ept->targ ); } /* Clean up the target list. */ delete st->eptVect; st->eptVect = 0; } /* Clear the epsilon transitions vector. */ st->epsilonTrans.empty(); } } void FsmAp::epsilonOp() { /* For merging process. */ MergeData md; setMisfitAccounting( true ); for ( StateList::Iter st = stateList; st.lte(); st++ ) st->owningGraph = 0; /* Perform merges. */ resolveEpsilonTrans( md ); /* Epsilons can caused merges which leave behind unreachable states. */ fillInStates( md ); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } /* Make a new maching by joining together a bunch of machines without making * any transitions between them. A negative finalId results in there being no * final id. */ void FsmAp::joinOp( int startId, int finalId, FsmAp **others, int numOthers ) { /* For the merging process. */ MergeData md; /* Set the owning machines. Start at one. Zero is reserved for the start * and final states. */ for ( StateList::Iter st = stateList; st.lte(); st++ ) st->owningGraph = 1; for ( int m = 0; m < numOthers; m++ ) { for ( StateList::Iter st = others[m]->stateList; st.lte(); st++ ) st->owningGraph = 2+m; } /* All machines loose start state status. */ unsetStartState(); for ( int m = 0; m < numOthers; m++ ) others[m]->unsetStartState(); /* Bring the other machines into this. */ for ( int m = 0; m < numOthers; m++ ) { /* Bring in the rest of other's entry points. */ copyInEntryPoints( others[m] ); others[m]->entryPoints.empty(); /* Merge the lists. This will move all the states from other into * this. No states will be deleted. */ stateList.append( others[m]->stateList ); assert( others[m]->misfitList.length() == 0 ); /* Move the final set data from other into this. */ finStateSet.insert( others[m]->finStateSet ); others[m]->finStateSet.empty(); /* Since other's list is empty, we can delete the fsm without * affecting any states. */ delete others[m]; } /* Look up the start entry point. */ EntryMapEl *enLow = 0, *enHigh = 0; bool findRes = entryPoints.findMulti( startId, enLow, enHigh ); if ( ! findRes ) { /* No start state. Set a default one and proceed with the join. Note * that the result of the join will be a very uninteresting machine. */ setStartState( addState() ); } else { /* There is at least one start state, create a state that will become * the new start state. */ StateAp *newStart = addState(); setStartState( newStart ); /* The start state is in an owning machine class all it's own. */ newStart->owningGraph = 0; /* Create the set of states to merge from. */ StateSet stateSet; for ( EntryMapEl *en = enLow; en <= enHigh; en++ ) stateSet.insert( en->value ); /* Merge in the set of start states into the new start state. */ mergeStates( md, newStart, stateSet.data, stateSet.length() ); } /* Take a copy of the final state set, before unsetting them all. This * will allow us to call clearOutData on the states that don't get * final state status back back. */ StateSet finStateSetCopy = finStateSet; /* Now all final states are unset. */ unsetAllFinStates(); if ( finalId >= 0 ) { /* Create the implicit final state. */ StateAp *finState = addState(); setFinState( finState ); /* Assign an entry into the final state on the final state entry id. Note * that there may already be an entry on this id. That's ok. Also set the * final state owning machine id. It's in a class all it's own. */ setEntry( finalId, finState ); finState->owningGraph = 0; } /* Hand over to workers for resolving epsilon trans. This will merge states * with the targets of their epsilon transitions. */ resolveEpsilonTrans( md ); /* Invoke the relinquish final callback on any states that did not get * final state status back. */ for ( StateSet::Iter st = finStateSetCopy; st.lte(); st++ ) { if ( !((*st)->stateBits & STB_ISFINAL) ) clearOutData( *st ); } /* Fill in any new states made from merging. */ fillInStates( md ); /* Joining can be messy. Instead of having misfit accounting on (which is * tricky here) do a full cleaning. */ removeUnreachableStates(); } void FsmAp::globOp( FsmAp **others, int numOthers ) { /* All other machines loose start states status. */ for ( int m = 0; m < numOthers; m++ ) others[m]->unsetStartState(); /* Bring the other machines into this. */ for ( int m = 0; m < numOthers; m++ ) { /* Bring in the rest of other's entry points. */ copyInEntryPoints( others[m] ); others[m]->entryPoints.empty(); /* Merge the lists. This will move all the states from other into * this. No states will be deleted. */ stateList.append( others[m]->stateList ); assert( others[m]->misfitList.length() == 0 ); /* Move the final set data from other into this. */ finStateSet.insert( others[m]->finStateSet ); others[m]->finStateSet.empty(); /* Since other's list is empty, we can delete the fsm without * affecting any states. */ delete others[m]; } } void FsmAp::deterministicEntry() { /* For the merging process. */ MergeData md; /* States may loose their entry points, turn on misfit accounting. */ setMisfitAccounting( true ); /* Get a copy of the entry map then clear all the entry points. As we * iterate the old entry map finding duplicates we will add the entry * points for the new states that we create. */ EntryMap prevEntry = entryPoints; unsetAllEntryPoints(); for ( int enId = 0; enId < prevEntry.length(); ) { /* Count the number of states on this entry key. */ int highId = enId; while ( highId < prevEntry.length() && prevEntry[enId].key == prevEntry[highId].key ) highId += 1; int numIds = highId - enId; if ( numIds == 1 ) { /* Only a single entry point, just set the entry. */ setEntry( prevEntry[enId].key, prevEntry[enId].value ); } else { /* Multiple entry points, need to create a new state and merge in * all the targets of entry points. */ StateAp *newEntry = addState(); for ( int en = enId; en < highId; en++ ) mergeStates( md, newEntry, prevEntry[en].value ); /* Add the new state as the single entry point. */ setEntry( prevEntry[enId].key, newEntry ); } enId += numIds; } /* The old start state may be unreachable. Remove the misfits and turn off * misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } /* Unset any final states that are no longer to be final due to final bits. */ void FsmAp::unsetKilledFinals() { /* Duplicate the final state set before we begin modifying it. */ StateSet fin( finStateSet ); for ( int s = 0; s < fin.length(); s++ ) { /* Check for killing bit. */ StateAp *state = fin.data[s]; if ( state->stateBits & STB_GRAPH1 ) { /* One final state is a killer, set to non-final. */ unsetFinState( state ); } /* Clear all killing bits. Non final states should never have had those * state bits set in the first place. */ state->stateBits &= ~STB_GRAPH1; } } /* Unset any final states that are no longer to be final due to final bits. */ void FsmAp::unsetIncompleteFinals() { /* Duplicate the final state set before we begin modifying it. */ StateSet fin( finStateSet ); for ( int s = 0; s < fin.length(); s++ ) { /* Check for one set but not the other. */ StateAp *state = fin.data[s]; if ( state->stateBits & STB_BOTH && (state->stateBits & STB_BOTH) != STB_BOTH ) { /* One state wants the other but it is not there. */ unsetFinState( state ); } /* Clear wanting bits. Non final states should never have had those * state bits set in the first place. */ state->stateBits &= ~STB_BOTH; } } /* Ensure that the start state is free of entry points (aside from the fact * that it is the start state). If the start state has entry points then Make a * new start state by merging with the old one. Useful before modifying start * transitions. If the existing start state has any entry points other than the * start state entry then modifying its transitions changes more than the start * transitions. So isolate the start state by separating it out such that it * only has start stateness as it's entry point. */ void FsmAp::isolateStartState( ) { /* For the merging process. */ MergeData md; /* Bail out if the start state is already isolated. */ if ( isStartStateIsolated() ) return; /* Turn on misfit accounting to possibly catch the old start state. */ setMisfitAccounting( true ); /* This will be the new start state. The existing start * state is merged with it. */ StateAp *prevStartState = startState; unsetStartState(); setStartState( addState() ); /* Merge the new start state with the old one to isolate it. */ mergeStates( md, startState, prevStartState ); /* Stfil and stateDict will be empty because the merging of the old start * state into the new one will not have any conflicting transitions. */ assert( md.stateDict.treeSize == 0 ); assert( md.stfillHead == 0 ); /* The old start state may be unreachable. Remove the misfits and turn off * misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } #ifdef LOG_CONDS void logCondSpace( CondSpace *condSpace ) { if ( condSpace == 0 ) cerr << ""; else { for ( CondSet::Iter csi = condSpace->condSet.last(); csi.gtb(); csi-- ) { if ( ! csi.last() ) cerr << ','; (*csi)->actionName( cerr ); } } } void logNewExpansion( Expansion *exp ) { cerr << "created expansion:" << endl; cerr << " range: " << exp->lowKey.getVal() << " .. " << exp->highKey.getVal() << endl; cerr << " fromCondSpace: "; logCondSpace( exp->fromCondSpace ); cerr << endl; cerr << " fromVals: " << exp->fromVals << endl; cerr << " toCondSpace: "; logCondSpace( exp->toCondSpace ); cerr << endl; cerr << " toValsList: "; for ( LongVect::Iter to = exp->toValsList; to.lte(); to++ ) cerr << " " << *to; cerr << endl; } #endif void FsmAp::findTransExpansions( ExpansionList &expansionList, StateAp *destState, StateAp *srcState ) { PairIter transCond( destState->outList.head, srcState->stateCondList.head ); for ( ; !transCond.end(); transCond++ ) { if ( transCond.userState == RangeOverlap ) { Expansion *expansion = new Expansion( transCond.s1Tel.lowKey, transCond.s1Tel.highKey ); expansion->fromTrans = new TransAp(*transCond.s1Tel.trans); expansion->fromTrans->fromState = 0; expansion->fromTrans->toState = transCond.s1Tel.trans->toState; expansion->fromCondSpace = 0; expansion->fromVals = 0; CondSpace *srcCS = transCond.s2Tel.trans->condSpace; expansion->toCondSpace = srcCS; long numTargVals = (1 << srcCS->condSet.length()); for ( long targVals = 0; targVals < numTargVals; targVals++ ) expansion->toValsList.append( targVals ); #ifdef LOG_CONDS logNewExpansion( expansion ); #endif expansionList.append( expansion ); } } } void FsmAp::findCondExpInTrans( ExpansionList &expansionList, StateAp *state, Key lowKey, Key highKey, CondSpace *fromCondSpace, CondSpace *toCondSpace, long fromVals, LongVect &toValsList ) { /* Make condition-space low and high keys for searching. */ TransAp searchTrans; searchTrans.lowKey = fromCondSpace->baseKey + fromVals * keyOps->alphSize() + (lowKey - keyOps->minKey); searchTrans.highKey = fromCondSpace->baseKey + fromVals * keyOps->alphSize() + (highKey - keyOps->minKey); searchTrans.prev = searchTrans.next = 0; PairIter pairIter( state->outList.head, &searchTrans ); for ( ; !pairIter.end(); pairIter++ ) { if ( pairIter.userState == RangeOverlap ) { /* Need to make character-space low and high keys from the range * overlap for the expansion object. */ Key expLowKey = pairIter.s1Tel.lowKey - fromCondSpace->baseKey - fromVals * keyOps->alphSize() + keyOps->minKey; Key expHighKey = pairIter.s1Tel.highKey - fromCondSpace->baseKey - fromVals * keyOps->alphSize() + keyOps->minKey; Expansion *expansion = new Expansion( expLowKey, expHighKey ); expansion->fromTrans = new TransAp(*pairIter.s1Tel.trans); expansion->fromTrans->fromState = 0; expansion->fromTrans->toState = pairIter.s1Tel.trans->toState; expansion->fromCondSpace = fromCondSpace; expansion->fromVals = fromVals; expansion->toCondSpace = toCondSpace; expansion->toValsList = toValsList; expansionList.append( expansion ); #ifdef LOG_CONDS logNewExpansion( expansion ); #endif } } } void FsmAp::findCondExpansions( ExpansionList &expansionList, StateAp *destState, StateAp *srcState ) { PairIter condCond( destState->stateCondList.head, srcState->stateCondList.head ); for ( ; !condCond.end(); condCond++ ) { if ( condCond.userState == RangeOverlap ) { /* Loop over all existing condVals . */ CondSet &destCS = condCond.s1Tel.trans->condSpace->condSet; long destLen = destCS.length(); /* Find the items in src cond set that are not in dest * cond set. These are the items that we must expand. */ CondSet srcOnlyCS = condCond.s2Tel.trans->condSpace->condSet; for ( CondSet::Iter dcsi = destCS; dcsi.lte(); dcsi++ ) srcOnlyCS.remove( *dcsi ); long srcOnlyLen = srcOnlyCS.length(); if ( srcOnlyCS.length() > 0 ) { #ifdef LOG_CONDS cerr << "there are " << srcOnlyCS.length() << " item(s) that are " "only in the srcCS" << endl; #endif CondSet mergedCS = destCS; mergedCS.insert( condCond.s2Tel.trans->condSpace->condSet ); CondSpace *fromCondSpace = addCondSpace( destCS ); CondSpace *toCondSpace = addCondSpace( mergedCS ); /* Loop all values in the dest space. */ for ( long destVals = 0; destVals < (1 << destLen); destVals++ ) { long basicVals = 0; for ( CondSet::Iter csi = destCS; csi.lte(); csi++ ) { if ( destVals & (1 << csi.pos()) ) { Action **cim = mergedCS.find( *csi ); long bitPos = (cim - mergedCS.data); basicVals |= 1 << bitPos; } } /* Loop all new values. */ LongVect expandToVals; for ( long soVals = 0; soVals < (1 << srcOnlyLen); soVals++ ) { long targVals = basicVals; for ( CondSet::Iter csi = srcOnlyCS; csi.lte(); csi++ ) { if ( soVals & (1 << csi.pos()) ) { Action **cim = mergedCS.find( *csi ); long bitPos = (cim - mergedCS.data); targVals |= 1 << bitPos; } } expandToVals.append( targVals ); } findCondExpInTrans( expansionList, destState, condCond.s1Tel.lowKey, condCond.s1Tel.highKey, fromCondSpace, toCondSpace, destVals, expandToVals ); } } } } } void FsmAp::doExpand( MergeData &md, StateAp *destState, ExpansionList &expList1 ) { for ( ExpansionList::Iter exp = expList1; exp.lte(); exp++ ) { for ( LongVect::Iter to = exp->toValsList; to.lte(); to++ ) { long targVals = *to; /* We will use the copy of the transition that was made when the * expansion was created. It will get used multiple times. Each * time we must set up the keys, everything else is constant and * and already prepared. */ TransAp *srcTrans = exp->fromTrans; srcTrans->lowKey = exp->toCondSpace->baseKey + targVals * keyOps->alphSize() + (exp->lowKey - keyOps->minKey); srcTrans->highKey = exp->toCondSpace->baseKey + targVals * keyOps->alphSize() + (exp->highKey - keyOps->minKey); TransList srcList; srcList.append( srcTrans ); outTransCopy( md, destState, srcList.head ); srcList.abandon(); } } } void FsmAp::doRemove( MergeData &md, StateAp *destState, ExpansionList &expList1 ) { for ( ExpansionList::Iter exp = expList1; exp.lte(); exp++ ) { Removal removal; if ( exp->fromCondSpace == 0 ) { removal.lowKey = exp->lowKey; removal.highKey = exp->highKey; } else { removal.lowKey = exp->fromCondSpace->baseKey + exp->fromVals * keyOps->alphSize() + (exp->lowKey - keyOps->minKey); removal.highKey = exp->fromCondSpace->baseKey + exp->fromVals * keyOps->alphSize() + (exp->highKey - keyOps->minKey); } removal.next = 0; TransList destList; PairIter pairIter( destState->outList.head, &removal ); for ( ; !pairIter.end(); pairIter++ ) { switch ( pairIter.userState ) { case RangeInS1: { TransAp *destTrans = pairIter.s1Tel.trans; destTrans->lowKey = pairIter.s1Tel.lowKey; destTrans->highKey = pairIter.s1Tel.highKey; destList.append( destTrans ); break; } case RangeInS2: break; case RangeOverlap: { TransAp *trans = pairIter.s1Tel.trans; detachTrans( trans->fromState, trans->toState, trans ); delete trans; break; } case BreakS1: { pairIter.s1Tel.trans = dupTrans( destState, pairIter.s1Tel.trans ); break; } case BreakS2: break; } } destState->outList.transfer( destList ); } } void FsmAp::mergeStateConds( StateAp *destState, StateAp *srcState ) { StateCondList destList; PairIter pairIter( destState->stateCondList.head, srcState->stateCondList.head ); for ( ; !pairIter.end(); pairIter++ ) { switch ( pairIter.userState ) { case RangeInS1: { StateCond *destCond = pairIter.s1Tel.trans; destCond->lowKey = pairIter.s1Tel.lowKey; destCond->highKey = pairIter.s1Tel.highKey; destList.append( destCond ); break; } case RangeInS2: { StateCond *newCond = new StateCond( *pairIter.s2Tel.trans ); newCond->lowKey = pairIter.s2Tel.lowKey; newCond->highKey = pairIter.s2Tel.highKey; destList.append( newCond ); break; } case RangeOverlap: { StateCond *destCond = pairIter.s1Tel.trans; StateCond *srcCond = pairIter.s2Tel.trans; CondSet mergedCondSet; mergedCondSet.insert( destCond->condSpace->condSet ); mergedCondSet.insert( srcCond->condSpace->condSet ); destCond->condSpace = addCondSpace( mergedCondSet ); destCond->lowKey = pairIter.s1Tel.lowKey; destCond->highKey = pairIter.s1Tel.highKey; destList.append( destCond ); break; } case BreakS1: pairIter.s1Tel.trans = new StateCond( *pairIter.s1Tel.trans ); break; case BreakS2: break; } } destState->stateCondList.transfer( destList ); } /* A state merge which represents the drawing in of leaving transitions. If * there is any out data then we duplicate the source state, transfer the out * data, then merge in the state. The new state will be reaped because it will * not be given any in transitions. */ void FsmAp::mergeStatesLeaving( MergeData &md, StateAp *destState, StateAp *srcState ) { if ( !hasOutData( destState ) ) mergeStates( md, destState, srcState ); else { StateAp *ssMutable = addState(); mergeStates( md, ssMutable, srcState ); transferOutData( ssMutable, destState ); for ( OutCondSet::Iter cond = destState->outCondSet; cond.lte(); cond++ ) embedCondition( md, ssMutable, cond->action, cond->sense ); mergeStates( md, destState, ssMutable ); } } void FsmAp::mergeStates( MergeData &md, StateAp *destState, StateAp **srcStates, int numSrc ) { for ( int s = 0; s < numSrc; s++ ) mergeStates( md, destState, srcStates[s] ); } void FsmAp::mergeStates( MergeData &md, StateAp *destState, StateAp *srcState ) { ExpansionList expList1; ExpansionList expList2; findTransExpansions( expList1, destState, srcState ); findCondExpansions( expList1, destState, srcState ); findTransExpansions( expList2, srcState, destState ); findCondExpansions( expList2, srcState, destState ); mergeStateConds( destState, srcState ); outTransCopy( md, destState, srcState->outList.head ); doExpand( md, destState, expList1 ); doExpand( md, destState, expList2 ); doRemove( md, destState, expList1 ); doRemove( md, destState, expList2 ); expList1.empty(); expList2.empty(); /* Get its bits and final state status. */ destState->stateBits |= ( srcState->stateBits & ~STB_ISFINAL ); if ( srcState->isFinState() ) setFinState( destState ); /* Draw in any properties of srcState into destState. */ if ( srcState == destState ) { /* Duplicate the list to protect against write to source. The * priorities sets are not copied in because that would have no * effect. */ destState->epsilonTrans.append( EpsilonTrans( srcState->epsilonTrans ) ); /* Get all actions, duplicating to protect against write to source. */ destState->toStateActionTable.setActions( ActionTable( srcState->toStateActionTable ) ); destState->fromStateActionTable.setActions( ActionTable( srcState->fromStateActionTable ) ); destState->outActionTable.setActions( ActionTable( srcState->outActionTable ) ); destState->outCondSet.insert( OutCondSet( srcState->outCondSet ) ); destState->errActionTable.setActions( ErrActionTable( srcState->errActionTable ) ); destState->eofActionTable.setActions( ActionTable( srcState->eofActionTable ) ); } else { /* Get the epsilons, out priorities. */ destState->epsilonTrans.append( srcState->epsilonTrans ); destState->outPriorTable.setPriors( srcState->outPriorTable ); /* Get all actions. */ destState->toStateActionTable.setActions( srcState->toStateActionTable ); destState->fromStateActionTable.setActions( srcState->fromStateActionTable ); destState->outActionTable.setActions( srcState->outActionTable ); destState->outCondSet.insert( srcState->outCondSet ); destState->errActionTable.setActions( srcState->errActionTable ); destState->eofActionTable.setActions( srcState->eofActionTable ); } } void FsmAp::fillInStates( MergeData &md ) { /* Merge any states that are awaiting merging. This will likey cause * other states to be added to the stfil list. */ StateAp *state = md.stfillHead; while ( state != 0 ) { StateSet *stateSet = &state->stateDictEl->stateSet; mergeStates( md, state, stateSet->data, stateSet->length() ); state = state->alg.next; } /* Delete the state sets of all states that are on the fill list. */ state = md.stfillHead; while ( state != 0 ) { /* Delete and reset the state set. */ delete state->stateDictEl; state->stateDictEl = 0; /* Next state in the stfill list. */ state = state->alg.next; } /* StateDict will still have its ptrs/size set but all of it's element * will be deleted so we don't need to clean it up. */ } void FsmAp::findEmbedExpansions( ExpansionList &expansionList, StateAp *destState, Action *condAction, bool sense ) { StateCondList destList; PairIter transCond( destState->outList.head, destState->stateCondList.head ); for ( ; !transCond.end(); transCond++ ) { switch ( transCond.userState ) { case RangeInS1: { if ( transCond.s1Tel.lowKey <= keyOps->maxKey ) { assert( transCond.s1Tel.highKey <= keyOps->maxKey ); /* Make a new state cond. */ StateCond *newStateCond = new StateCond( transCond.s1Tel.lowKey, transCond.s1Tel.highKey ); newStateCond->condSpace = addCondSpace( CondSet( condAction ) ); destList.append( newStateCond ); /* Create the expansion. */ Expansion *expansion = new Expansion( transCond.s1Tel.lowKey, transCond.s1Tel.highKey ); expansion->fromTrans = new TransAp(*transCond.s1Tel.trans); expansion->fromTrans->fromState = 0; expansion->fromTrans->toState = transCond.s1Tel.trans->toState; expansion->fromCondSpace = 0; expansion->fromVals = 0; expansion->toCondSpace = newStateCond->condSpace; expansion->toValsList.append( sense?1:0 ); #ifdef LOG_CONDS logNewExpansion( expansion ); #endif expansionList.append( expansion ); } break; } case RangeInS2: { /* Enhance state cond and find the expansion. */ StateCond *stateCond = transCond.s2Tel.trans; stateCond->lowKey = transCond.s2Tel.lowKey; stateCond->highKey = transCond.s2Tel.highKey; CondSet &destCS = stateCond->condSpace->condSet; long destLen = destCS.length(); CondSpace *fromCondSpace = stateCond->condSpace; CondSet mergedCS = destCS; mergedCS.insert( condAction ); CondSpace *toCondSpace = addCondSpace( mergedCS ); stateCond->condSpace = toCondSpace; destList.append( stateCond ); /* Loop all values in the dest space. */ for ( long destVals = 0; destVals < (1 << destLen); destVals++ ) { long basicVals = 0; for ( CondSet::Iter csi = destCS; csi.lte(); csi++ ) { if ( destVals & (1 << csi.pos()) ) { Action **cim = mergedCS.find( *csi ); long bitPos = (cim - mergedCS.data); basicVals |= 1 << bitPos; } } long targVals = basicVals; Action **cim = mergedCS.find( condAction ); long bitPos = (cim - mergedCS.data); targVals |= (sense?1:0) << bitPos; LongVect expandToVals( targVals ); findCondExpInTrans( expansionList, destState, transCond.s2Tel.lowKey, transCond.s2Tel.highKey, fromCondSpace, toCondSpace, destVals, expandToVals ); } break; } case RangeOverlap: case BreakS1: case BreakS2: assert( false ); break; } } destState->stateCondList.transfer( destList ); } void FsmAp::embedCondition( StateAp *state, Action *condAction, bool sense ) { MergeData md; ExpansionList expList; /* Turn on misfit accounting to possibly catch the old start state. */ setMisfitAccounting( true ); /* Worker. */ embedCondition( md, state, condAction, sense ); /* Fill in any states that were newed up as combinations of others. */ fillInStates( md ); /* Remove the misfits and turn off misfit accounting. */ removeMisfits(); setMisfitAccounting( false ); } void FsmAp::embedCondition( MergeData &md, StateAp *state, Action *condAction, bool sense ) { ExpansionList expList; findEmbedExpansions( expList, state, condAction, sense ); doExpand( md, state, expList ); doRemove( md, state, expList ); expList.empty(); } /* Check if a machine defines a single character. This is useful in validating * ranges and machines to export. */ bool FsmAp::checkSingleCharMachine() { /* Must have two states. */ if ( stateList.length() != 2 ) return false; /* The start state cannot be final. */ if ( startState->isFinState() ) return false; /* There should be only one final state. */ if ( finStateSet.length() != 1 ) return false; /* The final state cannot have any transitions out. */ if ( finStateSet[0]->outList.length() != 0 ) return false; /* The start state should have only one transition out. */ if ( startState->outList.length() != 1 ) return false; /* The singe transition out of the start state should not be a range. */ TransAp *startTrans = startState->outList.head; if ( startTrans->lowKey != startTrans->highKey ) return false; return true; } ragel-6.10/ragel/xmlcodegen.h0000664000175000017500000001156313065111230013043 00000000000000/* * Copyright 2005-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _XMLCODEGEN_H #define _XMLCODEGEN_H #include #include "avltree.h" #include "fsmgraph.h" #include "parsedata.h" #include "redfsm.h" /* Forwards. */ struct TransAp; struct FsmAp; struct ParseData; struct GenInlineList; struct CodeGenData; struct RedActionTable : public AvlTreeEl { RedActionTable( const ActionTable &key ) : key(key), id(0) { } const ActionTable &getKey() { return key; } ActionTable key; int id; }; typedef AvlTree ActionTableMap; struct NextRedTrans { Key lowKey, highKey; TransAp *trans; TransAp *next; void load() { if ( trans != 0 ) { next = trans->next; lowKey = trans->lowKey; highKey = trans->highKey; } } NextRedTrans( TransAp *t ) { trans = t; load(); } void increment() { trans = next; load(); } }; struct GenBase { GenBase( char *fsmName, ParseData *pd, FsmAp *fsm ); void appendTrans( TransListVect &outList, Key lowKey, Key highKey, TransAp *trans ); void reduceActionTables(); char *fsmName; ParseData *pd; FsmAp *fsm; ActionTableMap actionTableMap; int nextActionTableId; }; class XMLCodeGen : protected GenBase { public: XMLCodeGen( char *fsmName, ParseData *pd, FsmAp *fsm, std::ostream &out ); void writeXML( ); private: void writeStateActions( StateAp *state ); void writeStateList(); void writeStateConditions( StateAp *state ); void writeKey( Key key ); void writeText( InlineItem *item ); void writeGoto( InlineItem *item ); void writeGotoExpr( InlineItem *item ); void writeCall( InlineItem *item ); void writeCallExpr( InlineItem *item ); void writeNext( InlineItem *item ); void writeNextExpr( InlineItem *item ); void writeEntry( InlineItem *item ); void writeLmOnLast( InlineItem *item ); void writeLmOnNext( InlineItem *item ); void writeLmOnLagBehind( InlineItem *item ); void writeExports(); bool writeNameInst( NameInst *nameInst ); void writeEntryPoints(); void writeConditions(); void writeInlineList( InlineList *inlineList ); void writeActionList(); void writeActionTableList(); void reduceTrans( TransAp *trans ); void writeTransList( StateAp *state ); void writeEofTrans( StateAp *state ); void writeTrans( Key lowKey, Key highKey, TransAp *defTrans ); void writeAction( Action *action ); void writeLmSwitch( InlineItem *item ); void writeMachine(); void writeActionExec( InlineItem *item ); std::ostream &out; }; class BackendGen : protected GenBase { public: BackendGen( char *fsmName, ParseData *pd, FsmAp *fsm, CodeGenData *cgd ); void makeBackend( ); private: void makeGenInlineList( GenInlineList *outList, InlineList *inList ); void makeKey( GenInlineList *outList, Key key ); void makeText( GenInlineList *outList, InlineItem *item ); void makeLmOnLast( GenInlineList *outList, InlineItem *item ); void makeLmOnNext( GenInlineList *outList, InlineItem *item ); void makeLmOnLagBehind( GenInlineList *outList, InlineItem *item ); void makeActionExec( GenInlineList *outList, InlineItem *item ); void makeLmSwitch( GenInlineList *outList, InlineItem *item ); void makeSetTokend( GenInlineList *outList, long offset ); void makeSetAct( GenInlineList *outList, long lmId ); void makeSubList( GenInlineList *outList, InlineList *inlineList, GenInlineItem::Type type ); void makeTargetItem( GenInlineList *outList, NameInst *nameTarg, GenInlineItem::Type type ); void makeExecGetTokend( GenInlineList *outList ); void makeExports(); void makeMachine(); void makeActionList(); void makeAction( Action *action ); void makeActionTableList(); void makeConditions(); void makeEntryPoints(); bool makeNameInst( std::string &out, NameInst *nameInst ); void makeStateList(); void makeStateActions( StateAp *state ); void makeEofTrans( StateAp *state ); void makeStateConditions( StateAp *state ); void makeTransList( StateAp *state ); void makeTrans( Key lowKey, Key highKey, TransAp *trans ); void close_ragel_def(); CodeGenData *cgd; /* Collected during parsing. */ int curAction; int curActionTable; int curTrans; int curState; int curCondSpace; int curStateCond; }; #endif ragel-6.10/ragel/mlfgoto.cpp0000664000175000017500000001644413065111230012723 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "mlfgoto.h" #include "redfsm.h" #include "gendata.h" #include "bstmap.h" std::ostream &OCamlFGotoCodeGen::EXEC_ACTIONS() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* We are at the start of a glob, write the case. */ out << "and f" << redAct->actListId << " () =\n"; out << "\tbegin try\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); out << "\twith Goto_again -> () end;\n"; out << "\tdo_again ()\n"; } } return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &OCamlFGotoCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\t|" << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); // out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &OCamlFGotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false ); // out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFGotoCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\t| " << redAct->actListId+1 << " ->\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true ); // out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &OCamlFGotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << "\t\t| " << st->id << " -> "; /* Jump to the func. */ out << "f" << st->eofAction->actListId << " ()\n"; } } return out; } unsigned int OCamlFGotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; return act; } unsigned int OCamlFGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; return act; } unsigned int OCamlFGotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; return act; } void OCamlFGotoCodeGen::writeData() { if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); out << "exception Goto_again" << TOP_SEP(); } void OCamlFGotoCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " begin\n"; if ( redFsm->anyRegCurStateRef() ) out << " let _ps = ref 0 in\n"; if ( redFsm->anyConditions() ) out << " let _widec : " << WIDE_ALPH_TYPE() << " = ref 0 in\n"; out << "\n"; out << "\tlet rec do_start () =\n"; if ( !noEnd ) { testEofUsed = true; out << " if " << P() << " = " << PE() << " then\n" " do_test_eof ()\n" "\telse\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if " << vCS() << " = " << redFsm->errState->id << " then\n" " do_out ()\n" "\telse\n"; } out << "\tdo_resume ()\n"; out << "and do_resume () =\n"; if ( redFsm->anyFromStateActions() ) { out << " begin match " << AT(FSA(),vCS()) << " with\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" "\n"; } out << " begin match " << vCS() << " with\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " end\n" "\n"; TRANSITIONS() << "\n"; if ( redFsm->anyRegActions() ) EXEC_ACTIONS() << "\n"; out << "\tand do_again () =\n"; if ( redFsm->anyToStateActions() ) { out << " begin match " << AT(TSA(), vCS()) << " with\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " end;\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " match " << vCS() << " with\n" << " | " << redFsm->errState->id << " -> do_out ()\n" " | _ ->\n"; } out << "\t" << P() << " <- " << P() << " + 1;\n"; if ( !noEnd ) { out << " if " << P() << " <> " << PE() << " then\n" " do_resume ()\n" "\telse do_test_eof ()\n"; } else { out << " do_resume ()\n"; } // if ( testEofUsed ) out << "and do_test_eof () =\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if " << P() << " = " << vEOF() << " then\n" " begin\n"; if ( redFsm->anyEofTrans() ) { out << " match " << vCS() << " with\n"; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " | " << st->id << " -> tr" << st->eofTrans->id << " ()\n"; } SWITCH_DEFAULT() << ";\n"; // fall through } if ( redFsm->anyEofActions() ) { out << " try match " << AT(EA(), vCS()) << " with\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " \n" " with Goto_again -> do_again () \n"; } out << " end\n" "\n"; } else out << "\t()\n"; if ( outLabelUsed ) out << "\tand do_out () = ()\n"; out << "\tin do_start ()\n"; out << " end;\n"; } ragel-6.10/ragel/mlftable.h0000664000175000017500000000322313065111230012476 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MLFTABLE_H #define _MLFTABLE_H #include #include "mltable.h" /* Forwards. */ //struct CodeGenData; /* * OCamlFTabCodeGen */ class OCamlFTabCodeGen : public OCamlTabCodeGen { public: OCamlFTabCodeGen( ostream &out ) : OCamlTabCodeGen(out) {} private: std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); virtual void calcIndexSize(); }; #endif ragel-6.10/ragel/Makefile.am0000664000175000017500000000377313065111230012605 00000000000000 INCLUDES = -I$(top_srcdir)/aapl bin_PROGRAMS = ragel ragel_CXXFLAGS = -Wall ragel_SOURCES = \ buffer.h cdgoto.h cscodegen.h csipgoto.h inputdata.h rbxgoto.h \ rubyflat.h cdcodegen.h cdipgoto.h csfflat.h cssplit.h javacodegen.h \ redfsm.h rubyftable.h cdfflat.h cdsplit.h csfgoto.h cstable.h \ parsedata.h rlparse.h rubytable.h cdfgoto.h cdtable.h csflat.h \ dotcodegen.h parsetree.h rlscan.h version.h cdflat.h common.h \ csftable.h fsmgraph.h pcheck.h rubycodegen.h xmlcodegen.h cdftable.h \ csgoto.h gendata.h ragel.h rubyfflat.h \ gocodegen.h gotable.h goftable.h goflat.h gofflat.h gogoto.h gofgoto.h \ goipgoto.h gotablish.h \ mlcodegen.h mltable.h mlftable.h mlflat.h mlfflat.h mlgoto.h mlfgoto.h \ main.cpp parsetree.cpp parsedata.cpp fsmstate.cpp fsmbase.cpp \ fsmattach.cpp fsmmin.cpp fsmgraph.cpp fsmap.cpp rlscan.cpp rlparse.cpp \ inputdata.cpp common.cpp redfsm.cpp gendata.cpp cdcodegen.cpp \ cdtable.cpp cdftable.cpp cdflat.cpp cdfflat.cpp cdgoto.cpp cdfgoto.cpp \ cdipgoto.cpp cdsplit.cpp javacodegen.cpp rubycodegen.cpp rubytable.cpp \ rubyftable.cpp rubyflat.cpp rubyfflat.cpp rbxgoto.cpp cscodegen.cpp \ cstable.cpp csftable.cpp csflat.cpp csfflat.cpp csgoto.cpp csfgoto.cpp \ csipgoto.cpp cssplit.cpp dotcodegen.cpp xmlcodegen.cpp \ gocodegen.cpp gotable.cpp goftable.cpp goflat.cpp gofflat.cpp gogoto.cpp gofgoto.cpp \ goipgoto.cpp gotablish.cpp \ mlcodegen.cpp mltable.cpp mlftable.cpp mlflat.cpp mlfflat.cpp mlgoto.cpp mlfgoto.cpp BUILT_SOURCES = \ rlscan.cpp rlparse.h rlparse.cpp version.h version.h: Makefile echo '#define VERSION "$(PACKAGE_VERSION)"' > version.h echo '#define PUBDATE "$(PUBDATE)"' >> version.h EXTRA_DIST = rlscan.rl rlparse.kh rlparse.kl if BUILD_PARSERS CLEANFILES = \ rlscan.cpp rlparse.h rlparse.cpp rlparse.h: rlparse.kh kelbt -o $@ $< rlparse.cpp: rlparse.kl rlparse.kh kelbt -o $@ $< # This dependency comes from the import of the parser defines # into the scanner. rlscan.cpp: rlparse.h rlscan.cpp: rlscan.rl ragel -G2 -I$(builddir) -o $@ $< endif ragel-6.10/ragel/parsedata.h0000664000175000017500000002512213065111230012656 00000000000000/* * Copyright 2001-2008 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PARSEDATA_H #define _PARSEDATA_H #include #include #include #include "avlmap.h" #include "bstmap.h" #include "vector.h" #include "dlist.h" #include "fsmgraph.h" #include "compare.h" #include "vector.h" #include "common.h" #include "parsetree.h" /* Forwards. */ using std::ostream; struct VarDef; struct Join; struct Expression; struct Term; struct FactorWithAug; struct FactorWithLabel; struct FactorWithRep; struct FactorWithNeg; struct Factor; struct Literal; struct Range; struct RegExpr; struct ReItem; struct ReOrBlock; struct ReOrItem; struct LongestMatch; struct InputData; struct CodeGenData; typedef DList LmList; /* Graph dictionary. */ struct GraphDictEl : public AvlTreeEl, public DListEl { GraphDictEl( const char *k ) : key(k), value(0), isInstance(false) { } GraphDictEl( const char *k, VarDef *value ) : key(k), value(value), isInstance(false) { } const char *getKey() { return key; } const char *key; VarDef *value; bool isInstance; /* Location info of graph definition. Points to variable name of assignment. */ InputLoc loc; }; typedef AvlTree GraphDict; typedef DList GraphList; /* Priority name dictionary. */ typedef AvlMapEl PriorDictEl; typedef AvlMap PriorDict; /* Local error name dictionary. */ typedef AvlMapEl LocalErrDictEl; typedef AvlMap LocalErrDict; /* Tree of instantiated names. */ typedef BstMapEl NameMapEl; typedef BstMap NameMap; typedef Vector NameVect; typedef BstSet NameSet; /* Node in the tree of instantiated names. */ struct NameInst { NameInst( const InputLoc &loc, NameInst *parent, const char *name, int id, bool isLabel ) : loc(loc), parent(parent), name(name), id(id), isLabel(isLabel), isLongestMatch(false), numRefs(0), numUses(0), start(0), final(0) {} InputLoc loc; /* Keep parent pointers in the name tree to retrieve * fully qulified names. */ NameInst *parent; const char *name; int id; bool isLabel; bool isLongestMatch; int numRefs; int numUses; /* Names underneath us, excludes anonymous names. */ NameMap children; /* All names underneath us in order of appearance. */ NameVect childVect; /* Join scopes need an implicit "final" target. */ NameInst *start, *final; /* During a fsm generation walk, lists the names that are referenced by * epsilon operations in the current scope. After the link is made by the * epsilon reference and the join operation is complete, the label can * have its refcount decremented. Once there are no more references the * entry point can be removed from the fsm returned. */ NameVect referencedNames; /* Pointers for the name search queue. */ NameInst *prev, *next; /* Check if this name inst or any name inst below is referenced. */ bool anyRefsRec(); }; typedef DList NameInstList; /* Stack frame used in walking the name tree. */ struct NameFrame { NameInst *prevNameInst; int prevNameChild; NameInst *prevLocalScope; }; struct LengthDef { LengthDef( char *name ) : name(name) {} char *name; LengthDef *prev, *next; }; typedef DList LengthDefList; /* Class to collect information about the machine during the * parse of input. */ struct ParseData { /* Create a new parse data object. This is done at the beginning of every * fsm specification. */ ParseData( const char *fileName, char *sectionName, const InputLoc §ionLoc ); ~ParseData(); /* * Setting up the graph dict. */ /* Initialize a graph dict with the basic fsms. */ void initGraphDict(); void createBuiltin( const char *name, BuiltinMachine builtin ); /* Make a name id in the current name instantiation scope if it is not * already there. */ NameInst *addNameInst( const InputLoc &loc, const char *data, bool isLabel ); void makeRootNames(); void makeNameTree( GraphDictEl *gdNode ); void makeExportsNameTree(); void fillNameIndex( NameInst *from ); void printNameTree(); /* Increments the usage count on entry names. Names that are no longer * needed will have their entry points unset. */ void unsetObsoleteEntries( FsmAp *graph ); /* Resove name references in action code and epsilon transitions. */ NameSet resolvePart( NameInst *refFrom, const char *data, bool recLabelsOnly ); void resolveFrom( NameSet &result, NameInst *refFrom, const NameRef &nameRef, int namePos ); NameInst *resolveStateRef( const NameRef &nameRef, InputLoc &loc, Action *action ); void resolveNameRefs( InlineList *inlineList, Action *action ); void resolveActionNameRefs(); /* Set the alphabet type. If type types are not valid returns false. */ bool setAlphType( const InputLoc &loc, char *s1, char *s2 ); bool setAlphType( const InputLoc &loc, char *s1 ); /* Override one of the variables ragel uses. */ bool setVariable( char *var, InlineList *inlineList ); /* Unique actions. */ void removeDups( ActionTable &actionTable ); void removeActionDups( FsmAp *graph ); /* Dumping the name instantiation tree. */ void printNameInst( NameInst *nameInst, int level ); /* Make the graph from a graph dict node. Does minimization. */ FsmAp *makeInstance( GraphDictEl *gdNode ); FsmAp *makeSpecific( GraphDictEl *gdNode ); FsmAp *makeAll(); /* Checking the contents of actions. */ void checkAction( Action *action ); void checkInlineList( Action *act, InlineList *inlineList ); void analyzeAction( Action *action, InlineList *inlineList ); void analyzeGraph( FsmAp *graph ); void makeExports(); void prepareMachineGen( GraphDictEl *graphDictEl ); void prepareMachineGenTBWrapped( GraphDictEl *graphDictEl ); void generateXML( ostream &out ); void generateReduced( InputData &inputData ); FsmAp *sectionGraph; bool generatingSectionSubset; void initKeyOps(); /* * Data collected during the parse. */ /* Dictionary of graphs. Both instances and non-instances go here. */ GraphDict graphDict; /* The list of instances. */ GraphList instanceList; /* Dictionary of actions. Lets actions be defined and then referenced. */ ActionDict actionDict; /* Dictionary of named priorities. */ PriorDict priorDict; /* Dictionary of named local errors. */ LocalErrDict localErrDict; /* List of actions. Will be pasted into a switch statement. */ ActionList actionList; /* The id of the next priority name and label. */ int nextPriorKey, nextLocalErrKey, nextNameId, nextCondId; /* The default priority number key for a machine. This is active during * the parse of the rhs of a machine assignment. */ int curDefPriorKey; int curDefLocalErrKey; /* Alphabet type. */ HostType *userAlphType; bool alphTypeSet; InputLoc alphTypeLoc; /* Element type and get key expression. */ InlineList *getKeyExpr; InlineList *accessExpr; /* Stack management */ InlineList *prePushExpr; InlineList *postPopExpr; /* Overriding variables. */ InlineList *pExpr; InlineList *peExpr; InlineList *eofExpr; InlineList *csExpr; InlineList *topExpr; InlineList *stackExpr; InlineList *actExpr; InlineList *tokstartExpr; InlineList *tokendExpr; InlineList *dataExpr; /* The alphabet range. */ char *lowerNum, *upperNum; Key lowKey, highKey; InputLoc rangeLowLoc, rangeHighLoc; /* The name of the file the fsm is from, and the spec name. */ const char *fileName; char *sectionName; InputLoc sectionLoc; /* Counting the action and priority ordering. */ int curActionOrd; int curPriorOrd; /* Root of the name tree. One root is for the instantiated machines. The * other root is for exported definitions. */ NameInst *rootName; NameInst *exportsRootName; /* Name tree walking. */ NameInst *curNameInst; int curNameChild; /* The place where resolved epsilon transitions go. These cannot go into * the parse tree because a single epsilon op can resolve more than once * to different nameInsts if the machine it's in is used more than once. */ NameVect epsilonResolvedLinks; int nextEpsilonResolvedLink; /* Root of the name tree used for doing local name searches. */ NameInst *localNameScope; void setLmInRetLoc( InlineList *inlineList ); void initLongestMatchData(); void setLongestMatchData( FsmAp *graph ); void initNameWalk(); void initExportsNameWalk(); NameInst *nextNameScope() { return curNameInst->childVect[curNameChild]; } NameFrame enterNameScope( bool isLocal, int numScopes ); void popNameScope( const NameFrame &frame ); void resetNameScope( const NameFrame &frame ); /* Make name ids to name inst pointers. */ NameInst **nameIndex; /* Counter for assigning ids to longest match items. */ int nextLongestMatchId; bool lmRequiresErrorState; /* List of all longest match parse tree items. */ LmList lmList; Action *newAction( const char *name, InlineList *inlineList ); Action *initTokStart; int initTokStartOrd; Action *setTokStart; int setTokStartOrd; Action *initActId; int initActIdOrd; Action *setTokEnd; int setTokEndOrd; void beginProcessing() { ::condData = &thisCondData; ::keyOps = &thisKeyOps; } CondData thisCondData; KeyOps thisKeyOps; ExportList exportList; LengthDefList lengthDefList; CodeGenData *cgd; }; void afterOpMinimize( FsmAp *fsm, bool lastInSeq = true ); Key makeFsmKeyHex( char *str, const InputLoc &loc, ParseData *pd ); Key makeFsmKeyDec( char *str, const InputLoc &loc, ParseData *pd ); Key makeFsmKeyNum( char *str, const InputLoc &loc, ParseData *pd ); Key makeFsmKeyChar( char c, ParseData *pd ); void makeFsmKeyArray( Key *result, char *data, int len, ParseData *pd ); void makeFsmUniqueKeyArray( KeySet &result, char *data, int len, bool caseInsensitive, ParseData *pd ); FsmAp *makeBuiltin( BuiltinMachine builtin, ParseData *pd ); FsmAp *dotFsm( ParseData *pd ); FsmAp *dotStarFsm( ParseData *pd ); void errorStateLabels( const NameSet &locations ); #endif ragel-6.10/ragel/gocodegen.cpp0000664000175000017500000004120313065111230013175 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "gocodegen.h" #include "ragel.h" #include "redfsm.h" #include "gendata.h" #include #include #include using std::ostream; using std::ostringstream; using std::string; using std::cerr; using std::endl; using std::istream; using std::ifstream; using std::ostream; using std::ios; using std::cin; using std::cout; using std::cerr; using std::endl; /* * Go Specific */ void goLineDirective( ostream &out, const char *fileName, int line ) { out << "//line " << fileName << ":" << line << endl; } void GoCodeGen::genLineDirective( ostream &out ) { std::streambuf *sbuf = out.rdbuf(); output_filter *filter = static_cast(sbuf); goLineDirective( out, filter->fileName, filter->line + 1 ); } unsigned int GoCodeGen::arrayTypeSize( unsigned long maxVal ) { long long maxValLL = (long long) maxVal; HostType *arrayType = keyOps->typeSubsumes( maxValLL ); assert( arrayType != 0 ); return arrayType->size; } string GoCodeGen::ARRAY_TYPE( unsigned long maxVal ) { long long maxValLL = (long long) maxVal; HostType *arrayType = keyOps->typeSubsumes( maxValLL ); assert( arrayType != 0 ); string ret = arrayType->data1; if ( arrayType->data2 != 0 ) { ret += " "; ret += arrayType->data2; } return ret; } /* Write out the fsm name. */ string GoCodeGen::FSM_NAME() { return fsmName; } /* Emit the offset of the start state as a decimal integer. */ string GoCodeGen::START_STATE_ID() { ostringstream ret; ret << redFsm->startState->id; return ret.str(); }; /* Write out the array of actions. */ std::ostream &GoCodeGen::ACTIONS_ARRAY() { out << " 0, "; int totalActions = 1; for ( GenActionTableMap::Iter act = redFsm->actionMap; act.lte(); act++ ) { /* Write out the length, which will never be the last character. */ out << act->key.length() << ", "; if ( totalActions++ % IALL == 0 ) out << endl << " "; for ( GenActionTable::Iter item = act->key; item.lte(); item++ ) { out << item->value->actionId << ", "; if ( ! (act.last() && item.last()) ) { if ( totalActions++ % IALL == 0 ) out << endl << " "; } } } out << endl; return out; } string GoCodeGen::ACCESS() { ostringstream ret; if ( accessExpr != 0 ) INLINE_LIST( ret, accessExpr, 0, false, false ); return ret.str(); } string GoCodeGen::P() { ostringstream ret; if ( pExpr == 0 ) ret << "p"; else { ret << "("; INLINE_LIST( ret, pExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::PE() { ostringstream ret; if ( peExpr == 0 ) ret << "pe"; else { ret << "("; INLINE_LIST( ret, peExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::vEOF() { ostringstream ret; if ( eofExpr == 0 ) ret << "eof"; else { ret << "("; INLINE_LIST( ret, eofExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::vCS() { ostringstream ret; if ( csExpr == 0 ) ret << ACCESS() << "cs"; else { /* Emit the user supplied method of retrieving the key. */ ret << "("; INLINE_LIST( ret, csExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::TOP() { ostringstream ret; if ( topExpr == 0 ) ret << ACCESS() + "top"; else { ret << "("; INLINE_LIST( ret, topExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::STACK() { ostringstream ret; if ( stackExpr == 0 ) ret << ACCESS() + "stack"; else { ret << "("; INLINE_LIST( ret, stackExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::ACT() { ostringstream ret; if ( actExpr == 0 ) ret << ACCESS() + "act"; else { ret << "("; INLINE_LIST( ret, actExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::TOKSTART() { ostringstream ret; if ( tokstartExpr == 0 ) ret << ACCESS() + "ts"; else { ret << "("; INLINE_LIST( ret, tokstartExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::TOKEND() { ostringstream ret; if ( tokendExpr == 0 ) ret << ACCESS() + "te"; else { ret << "("; INLINE_LIST( ret, tokendExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::GET_WIDE_KEY() { if ( redFsm->anyConditions() ) return "_widec"; else return GET_KEY(); } string GoCodeGen::GET_WIDE_KEY( RedStateAp *state ) { if ( state->stateCondList.length() > 0 ) return "_widec"; else return GET_KEY(); } string GoCodeGen::GET_KEY() { ostringstream ret; if ( getKeyExpr != 0 ) { /* Emit the user supplied method of retrieving the key. */ ret << "("; INLINE_LIST( ret, getKeyExpr, 0, false, false ); ret << ")"; } else { /* Expression for retrieving the key, use simple dereference. */ ret << DATA() << "[" << P() << "]"; } return ret.str(); } /* Write out level number of tabs. Makes the nested binary search nice * looking. */ string GoCodeGen::TABS( int level ) { string result; while ( level-- > 0 ) result += "\t"; return result; } /* Write out a key from the fsm code gen. Depends on wether or not the key is * signed. */ string GoCodeGen::KEY( Key key ) { ostringstream ret; if ( keyOps->isSigned || !hostLang->explicitUnsigned ) ret << key.getVal(); else ret << (unsigned long) key.getVal() << 'u'; return ret.str(); } bool GoCodeGen::isAlphTypeSigned() { return keyOps->isSigned; } bool GoCodeGen::isWideAlphTypeSigned() { string ret; if ( redFsm->maxKey <= keyOps->maxKey ) return isAlphTypeSigned(); else { long long maxKeyVal = redFsm->maxKey.getLongLong(); HostType *wideType = keyOps->typeSubsumes( keyOps->isSigned, maxKeyVal ); return wideType->isSigned; } } string GoCodeGen::WIDE_KEY( RedStateAp *state, Key key ) { if ( state->stateCondList.length() > 0 ) { ostringstream ret; if ( isWideAlphTypeSigned() ) ret << key.getVal(); else ret << (unsigned long) key.getVal() << 'u'; return ret.str(); } else { return KEY( key ); } } void GoCodeGen::EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ) { /* The parser gives fexec two children. The double brackets are for D * code. If the inline list is a single word it will get interpreted as a * C-style cast by the D compiler. */ ret << P() << " = ("; INLINE_LIST( ret, item->children, targState, inFinish, false ); ret << ") - 1" << endl; } void GoCodeGen::LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish, bool csForced ) { ret << " switch " << ACT() << " {" << endl; for ( GenInlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ if ( lma->lmId < 0 ) { ret << " default:" << endl; } else ret << " case " << lma->lmId << ":" << endl; /* Write the block and close it off. */ ret << " {"; INLINE_LIST( ret, lma->children, targState, inFinish, csForced ); ret << "}" << endl; } ret << " }" << endl << " "; } void GoCodeGen::SET_ACT( ostream &ret, GenInlineItem *item ) { ret << ACT() << " = " << item->lmId << ";"; } void GoCodeGen::SET_TOKEND( ostream &ret, GenInlineItem *item ) { /* The tokend action sets tokend. */ ret << TOKEND() << " = " << P(); if ( item->offset != 0 ) out << "+" << item->offset; out << endl; } void GoCodeGen::GET_TOKEND( ostream &ret, GenInlineItem *item ) { ret << TOKEND(); } void GoCodeGen::INIT_TOKSTART( ostream &ret, GenInlineItem *item ) { ret << TOKSTART() << " = " << NULL_ITEM() << endl; } void GoCodeGen::INIT_ACT( ostream &ret, GenInlineItem *item ) { ret << ACT() << " = 0" << endl; } void GoCodeGen::SET_TOKSTART( ostream &ret, GenInlineItem *item ) { ret << TOKSTART() << " = " << P() << endl; } void GoCodeGen::SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish, bool csForced ) { if ( item->children->length() > 0 ) { /* Write the block and close it off. */ ret << "{"; INLINE_LIST( ret, item->children, targState, inFinish, csForced ); ret << "}"; } } /* Write out an inline tree structure. Walks the list and possibly calls out * to virtual functions than handle language specific items in the tree. */ void GoCodeGen::INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish, bool csForced ) { for ( GenInlineList::Iter item = *inlineList; item.lte(); item++ ) { switch ( item->type ) { case GenInlineItem::Text: ret << item->data; break; case GenInlineItem::Goto: GOTO( ret, item->targState->id, inFinish ); break; case GenInlineItem::Call: CALL( ret, item->targState->id, targState, inFinish ); break; case GenInlineItem::Next: NEXT( ret, item->targState->id, inFinish ); break; case GenInlineItem::Ret: RET( ret, inFinish ); break; case GenInlineItem::PChar: ret << P(); break; case GenInlineItem::Char: ret << GET_KEY(); break; case GenInlineItem::Hold: ret << P() << "--" << endl; break; case GenInlineItem::Exec: EXEC( ret, item, targState, inFinish ); break; case GenInlineItem::Curs: CURS( ret, inFinish ); break; case GenInlineItem::Targs: TARGS( ret, inFinish, targState ); break; case GenInlineItem::Entry: ret << item->targState->id; break; case GenInlineItem::GotoExpr: GOTO_EXPR( ret, item, inFinish ); break; case GenInlineItem::CallExpr: CALL_EXPR( ret, item, targState, inFinish ); break; case GenInlineItem::NextExpr: NEXT_EXPR( ret, item, inFinish ); break; case GenInlineItem::LmSwitch: LM_SWITCH( ret, item, targState, inFinish, csForced ); break; case GenInlineItem::LmSetActId: SET_ACT( ret, item ); break; case GenInlineItem::LmSetTokEnd: SET_TOKEND( ret, item ); break; case GenInlineItem::LmGetTokEnd: GET_TOKEND( ret, item ); break; case GenInlineItem::LmInitTokStart: INIT_TOKSTART( ret, item ); break; case GenInlineItem::LmInitAct: INIT_ACT( ret, item ); break; case GenInlineItem::LmSetTokStart: SET_TOKSTART( ret, item ); break; case GenInlineItem::SubAction: SUB_ACTION( ret, item, targState, inFinish, csForced ); break; case GenInlineItem::Break: BREAK( ret, targState, csForced ); break; } } } /* Write out paths in line directives. Escapes any special characters. */ string GoCodeGen::LDIR_PATH( char *path ) { ostringstream ret; for ( char *pc = path; *pc != 0; pc++ ) { if ( *pc == '\\' ) ret << "\\\\"; else ret << *pc; } return ret.str(); } void GoCodeGen::ACTION( ostream &ret, GenAction *action, int targState, bool inFinish, bool csForced ) { /* Write the preprocessor line info for going into the source file. */ goLineDirective( ret, action->loc.fileName, action->loc.line ); /* Write the block and close it off. */ INLINE_LIST( ret, action->inlineList, targState, inFinish, csForced ); ret << endl; } void GoCodeGen::CONDITION( ostream &ret, GenAction *condition ) { INLINE_LIST( ret, condition->inlineList, 0, false, false ); } string GoCodeGen::ERROR_STATE() { ostringstream ret; if ( redFsm->errState != 0 ) ret << redFsm->errState->id; else ret << "-1"; return ret.str(); } string GoCodeGen::FIRST_FINAL_STATE() { ostringstream ret; if ( redFsm->firstFinState != 0 ) ret << redFsm->firstFinState->id; else ret << redFsm->nextStateId; return ret.str(); } void GoCodeGen::writeInit() { out << " {" << endl; if ( !noCS ) out << " " << vCS() << " = " << START() << endl; /* If there are any calls, then the stack top needs initialization. */ if ( redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << " " << TOP() << " = 0" << endl; if ( hasLongestMatch ) { out << " " << TOKSTART() << " = " << NULL_ITEM() << endl << " " << TOKEND() << " = " << NULL_ITEM() << endl << " " << ACT() << " = 0" << endl; } out << " }" << endl; } string GoCodeGen::DATA() { ostringstream ret; if ( dataExpr == 0 ) ret << ACCESS() + "data"; else { ret << "("; INLINE_LIST( ret, dataExpr, 0, false, false ); ret << ")"; } return ret.str(); } string GoCodeGen::DATA_PREFIX() { if ( !noPrefix ) return FSM_NAME() + "_"; return ""; } /* Emit the alphabet data type. */ string GoCodeGen::ALPH_TYPE() { string ret = keyOps->alphType->data1; if ( keyOps->alphType->data2 != 0 ) { ret += " "; ret += + keyOps->alphType->data2; } return ret; } /* Emit the alphabet data type. */ string GoCodeGen::WIDE_ALPH_TYPE() { string ret; if ( redFsm->maxKey <= keyOps->maxKey ) ret = ALPH_TYPE(); else { long long maxKeyVal = redFsm->maxKey.getLongLong(); HostType *wideType = keyOps->typeSubsumes( keyOps->isSigned, maxKeyVal ); assert( wideType != 0 ); ret = wideType->data1; if ( wideType->data2 != 0 ) { ret += " "; ret += wideType->data2; } } return ret; } void GoCodeGen::STATE_IDS() { if ( redFsm->startState != 0 ) CONST( "int", START() ) << " = " << START_STATE_ID() << endl; if ( !noFinal ) CONST( "int" , FIRST_FINAL() ) << " = " << FIRST_FINAL_STATE() << endl; if ( !noError ) CONST( "int", ERROR() ) << " = " << ERROR_STATE() << endl; out << endl; if ( !noEntry && entryPointNames.length() > 0 ) { for ( EntryNameVect::Iter en = entryPointNames; en.lte(); en++ ) { CONST( "int", DATA_PREFIX() + "en_" + *en ) << " = " << entryPointIds[en.pos()] << endl; } out << endl; } } void GoCodeGen::writeStart() { out << START_STATE_ID(); } void GoCodeGen::writeFirstFinal() { out << FIRST_FINAL_STATE(); } void GoCodeGen::writeError() { out << ERROR_STATE(); } void GoCodeGen::finishRagelDef() { if ( codeStyle == GenGoto || codeStyle == GenFGoto || codeStyle == GenIpGoto || codeStyle == GenSplit ) { /* For directly executable machines there is no required state * ordering. Choose a depth-first ordering to increase the * potential for fall-throughs. */ redFsm->depthFirstOrdering(); } else { /* The frontend will do this for us, but it may be a good idea to * force it if the intermediate file is edited. */ redFsm->sortByStateId(); } /* Choose default transitions and the single transition. */ redFsm->chooseDefaultSpan(); /* Maybe do flat expand, otherwise choose single. */ if ( codeStyle == GenFlat || codeStyle == GenFFlat ) redFsm->makeFlat(); else redFsm->chooseSingle(); /* If any errors have occured in the input file then don't write anything. */ if ( gblErrorCount > 0 ) return; if ( codeStyle == GenSplit ) redFsm->partitionFsm( numSplitPartitions ); if ( codeStyle == GenIpGoto || codeStyle == GenSplit ) redFsm->setInTrans(); /* Anlayze Machine will find the final action reference counts, among * other things. We will use these in reporting the usage * of fsm directives in action code. */ analyzeMachine(); /* Determine if we should use indicies. */ calcIndexSize(); } ostream &GoCodeGen::source_warning( const InputLoc &loc ) { cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": warning: "; return cerr; } ostream &GoCodeGen::source_error( const InputLoc &loc ) { gblErrorCount += 1; assert( sourceFileName != 0 ); cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": "; return cerr; } /* * Go implementation. * */ std::ostream &GoCodeGen::OPEN_ARRAY( string type, string name ) { out << "var " << name << " []" << type << " = []" << type << "{" << endl; return out; } std::ostream &GoCodeGen::CLOSE_ARRAY() { return out << "}" << endl; } std::ostream &GoCodeGen::STATIC_VAR( string type, string name ) { out << "var " << name << " " << type; return out; } std::ostream &GoCodeGen::CONST( string type, string name ) { out << "const " << name << " " << type; return out; } string GoCodeGen::UINT( ) { return "uint"; } string GoCodeGen::INT() { return "int"; } string GoCodeGen::CAST( string type, string expr ) { return type + "(" + expr + ")"; } string GoCodeGen::NULL_ITEM() { return "0"; } void GoCodeGen::writeExports() { if ( exportList.length() > 0 ) { for ( ExportList::Iter ex = exportList; ex.lte(); ex++ ) { out << "const " << DATA_PREFIX() << "ex_" << ex->name << " = " << KEY(ex->key) << endl; } out << endl; } } ragel-6.10/ragel/cdfgoto.cpp0000664000175000017500000001543213065111230012675 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdfgoto.h" #include "redfsm.h" #include "gendata.h" #include "bstmap.h" std::ostream &FGotoCodeGen::EXEC_ACTIONS() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { /* We are at the start of a glob, write the case. */ out << "f" << redAct->actListId << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tgoto _again;\n"; } } return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FGotoCodeGen::TO_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numToStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } /* Write out the function switch. This switch is keyed on the values * of the func index. */ std::ostream &FGotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numFromStateRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FGotoCodeGen::EOF_ACTION_SWITCH() { /* Loop the actions. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numEofRefs > 0 ) { /* Write the entry label. */ out << "\tcase " << redAct->actListId+1 << ":\n"; /* Write each action in the list of action items. */ for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ ) ACTION( out, item->value, 0, true, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FGotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << "\t\tcase " << st->id << ": "; /* Jump to the func. */ out << "goto f" << st->eofAction->actListId << ";\n"; } } return out; } unsigned int FGotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->actListId+1; return act; } unsigned int FGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->actListId+1; return act; } unsigned int FGotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->actListId+1; return act; } void FGotoCodeGen::writeData() { if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void FGotoCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n"; if ( redFsm->anyRegCurStateRef() ) out << " int _ps = 0;\n"; if ( redFsm->anyConditions() ) out << " " << WIDE_ALPH_TYPE() << " _widec;\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " switch ( " << FSA() << "[" << vCS() << "] ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } out << " switch ( " << vCS() << " ) {\n"; STATE_GOTOS(); SWITCH_DEFAULT() << " }\n" "\n"; TRANSITIONS() << "\n"; if ( redFsm->anyRegActions() ) EXEC_ACTIONS() << "\n"; out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " switch ( " << TSA() << "[" << vCS() << "] ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " switch ( " << vCS() << " ) {\n"; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->eofTrans != 0 ) out << " case " << st->id << ": goto tr" << st->eofTrans->id << ";\n"; } SWITCH_DEFAULT() << " }\n"; } if ( redFsm->anyEofActions() ) { out << " switch ( " << EA() << "[" << vCS() << "] ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/ragel.h0000664000175000017500000000507013065111230012004 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _RAGEL_H #define _RAGEL_H #include #include #include #include #include "vector.h" #include "config.h" #include "common.h" #define PROGNAME "ragel" /* Target output style. */ enum CodeStyle { GenTables, GenFTables, GenFlat, GenFFlat, GenGoto, GenFGoto, GenIpGoto, GenSplit }; /* To what degree are machine minimized. */ enum MinimizeLevel { MinimizeApprox, MinimizeStable, MinimizePartition1, MinimizePartition2 }; enum MinimizeOpt { MinimizeNone, MinimizeEnd, MinimizeMostOps, MinimizeEveryOp }; /* Target implementation */ enum RubyImplEnum { MRI, Rubinius }; /* Options. */ extern MinimizeLevel minimizeLevel; extern MinimizeOpt minimizeOpt; extern const char *machineSpec, *machineName; extern bool printStatistics; extern bool wantDupsRemoved; extern bool generateDot; extern bool generateXML; extern RubyImplEnum rubyImpl; /* Error reporting format. */ enum ErrorFormat { ErrorFormatGNU, ErrorFormatMSVC, }; extern ErrorFormat errorFormat; extern int gblErrorCount; extern char mainMachine[]; InputLoc makeInputLoc( const char *fileName, int line = 0, int col = 0 ); std::ostream &operator<<( std::ostream &out, const InputLoc &loc ); /* Error reporting. */ std::ostream &error(); std::ostream &error( const InputLoc &loc ); std::ostream &warning( const InputLoc &loc ); struct XmlParser; void xmlEscapeHost( std::ostream &out, char *data, long len ); extern CodeStyle codeStyle; /* IO filenames and stream. */ extern bool displayPrintables; extern int gblErrorCount; /* Options. */ extern int numSplitPartitions; extern bool noLineDirectives; std::ostream &error(); /* Target language and output style. */ extern CodeStyle codeStyle; extern int numSplitPartitions; extern bool noLineDirectives; #endif ragel-6.10/ragel/cdflat.cpp0000664000175000017500000005037613065111230012513 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ragel.h" #include "cdflat.h" #include "redfsm.h" #include "gendata.h" std::ostream &FlatCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; out << act; return out; } std::ostream &FlatCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; out << act; return out; } std::ostream &FlatCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; out << act; return out; } std::ostream &FlatCodeGen::TRANS_ACTION( RedTransAp *trans ) { /* If there are actions, emit them. Otherwise emit zero. */ int act = 0; if ( trans->action != 0 ) act = trans->action->location+1; out << act; return out; } std::ostream &FlatCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FlatCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FlatCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, true, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FlatCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break */ out << "\tcase " << act->actionId << ":\n"; ACTION( out, act, 0, false, false ); out << "\tbreak;\n"; } } genLineDirective( out ); return out; } std::ostream &FlatCodeGen::FLAT_INDEX_OFFSET() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ if ( st->transList != 0 ) curIndOffset += keyOps->span( st->lowKey, st->highKey ); if ( st->defTrans != 0 ) curIndOffset += 1; } out << "\n"; return out; } std::ostream &FlatCodeGen::KEY_SPANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->transList != 0 ) span = keyOps->span( st->lowKey, st->highKey ); out << span; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &FlatCodeGen::TO_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ TO_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &FlatCodeGen::FROM_STATE_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ FROM_STATE_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &FlatCodeGen::EOF_ACTIONS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ EOF_ACTION(st); if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &FlatCodeGen::EOF_TRANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write any eof action. */ long trans = 0; if ( st->eofTrans != 0 ) { assert( st->eofTrans->pos >= 0 ); trans = st->eofTrans->pos+1; } out << trans; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &FlatCodeGen::COND_KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just cond low key and cond high key. */ out << KEY( st->condLowKey ) << ", "; out << KEY( st->condHighKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &FlatCodeGen::COND_KEY_SPANS() { out << "\t"; int totalStateNum = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write singles length. */ unsigned long long span = 0; if ( st->condList != 0 ) span = keyOps->span( st->condLowKey, st->condHighKey ); out << span; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } } out << "\n"; return out; } std::ostream &FlatCodeGen::CONDS() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->condList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { if ( st->condList[pos] != 0 ) out << st->condList[pos]->condSpaceId + 1 << ", "; else out << "0, "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &FlatCodeGen::COND_INDEX_OFFSET() { out << "\t"; int totalStateNum = 0, curIndOffset = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Write the index offset. */ out << curIndOffset; if ( !st.last() ) { out << ", "; if ( ++totalStateNum % IALL == 0 ) out << "\n\t"; } /* Move the index offset ahead. */ if ( st->condList != 0 ) curIndOffset += keyOps->span( st->condLowKey, st->condHighKey ); } out << "\n"; return out; } std::ostream &FlatCodeGen::KEYS() { out << '\t'; int totalTrans = 0; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* Emit just low key and high key. */ out << KEY( st->lowKey ) << ", "; out << KEY( st->highKey ) << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &FlatCodeGen::INDICIES() { int totalTrans = 0; out << '\t'; for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st->transList != 0 ) { /* Walk the singles. */ unsigned long long span = keyOps->span( st->lowKey, st->highKey ); for ( unsigned long long pos = 0; pos < span; pos++ ) { out << st->transList[pos]->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } } /* The state's default index goes next. */ if ( st->defTrans != 0 ) out << st->defTrans->id << ", "; if ( ++totalTrans % IALL == 0 ) out << "\n\t"; } /* Output one last number so we don't have to figure out when the last * entry is and avoid writing a comma. */ out << 0 << "\n"; return out; } std::ostream &FlatCodeGen::TRANS_TARGS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalStates = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Save the position. Needed for eofTargs. */ RedTransAp *trans = transPtrs[t]; trans->pos = t; /* Write out the target state. */ out << trans->targ->id; if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalStates % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } std::ostream &FlatCodeGen::TRANS_ACTIONS() { /* Transitions must be written ordered by their id. */ RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()]; for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) transPtrs[trans->id] = trans; /* Keep a count of the num of items in the array written. */ out << '\t'; int totalAct = 0; for ( int t = 0; t < redFsm->transSet.length(); t++ ) { /* Write the function for the transition. */ RedTransAp *trans = transPtrs[t]; TRANS_ACTION( trans ); if ( t < redFsm->transSet.length()-1 ) { out << ", "; if ( ++totalAct % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] transPtrs; return out; } void FlatCodeGen::LOCATE_TRANS() { out << " _keys = " << ARR_OFF( K(), "(" + vCS() + "<<1)" ) << ";\n" " _inds = " << ARR_OFF( I(), IO() + "[" + vCS() + "]" ) << ";\n" "\n" " _slen = " << SP() << "[" << vCS() << "];\n" " _trans = _inds[ _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= _keys[1] ?\n" " " << GET_WIDE_KEY() << " - _keys[0] : _slen ];\n" "\n"; } void FlatCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "{"; ret << vCS() << " = " << gotoDest << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void FlatCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "{"; ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << "); "; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void FlatCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void FlatCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void FlatCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void FlatCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); ret << ");"; } void FlatCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{"; ret << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << ";"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void FlatCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false, false ); } ret << "{" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish, false ); ret << ");"; if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; if ( prePushExpr != 0 ) ret << "}"; } void FlatCodeGen::RET( ostream &ret, bool inFinish ) { ret << "{" << vCS() << " = " << STACK() << "[--" << TOP() << "];"; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false, false ); ret << "}"; } if ( inFinish && !noEnd ) EOF_CHECK( ret ); ret << CTRL_FLOW() << "goto _again;"; ret << "}"; } void FlatCodeGen::BREAK( ostream &ret, int targState, bool csForced ) { outLabelUsed = true; ret << "{" << P() << "++; " << CTRL_FLOW() << "goto _out; }"; } void FlatCodeGen::writeData() { /* If there are any transtion functions then output the array. If there * are none, don't bother emitting an empty array that won't be used. */ if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyConditions() ) { OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() ); COND_KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() ); COND_KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() ); CONDS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() ); COND_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; } OPEN_ARRAY( WIDE_ALPH_TYPE(), K() ); KEYS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() ); KEY_SPANS(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() ); FLAT_INDEX_OFFSET(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() ); INDICIES(); CLOSE_ARRAY() << "\n"; OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() ); TRANS_TARGS(); CLOSE_ARRAY() << "\n"; if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() ); TRANS_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofTrans() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() ); EOF_TRANS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void FlatCodeGen::COND_TRANSLATE() { out << " _widec = " << GET_KEY() << ";\n"; out << " _keys = " << ARR_OFF( CK(), "(" + vCS() + "<<1)" ) << ";\n" " _conds = " << ARR_OFF( C(), CO() + "[" + vCS() + "]" ) << ";\n" "\n" " _slen = " << CSP() << "[" << vCS() << "];\n" " _cond = _slen > 0 && _keys[0] <=" << GET_WIDE_KEY() << " &&\n" " " << GET_WIDE_KEY() << " <= _keys[1] ?\n" " _conds[" << GET_WIDE_KEY() << " - _keys[0]] : 0;\n" "\n"; out << " switch ( _cond ) {\n"; for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) { GenCondSpace *condSpace = csi; out << " case " << condSpace->condSpaceId + 1 << ": {\n"; out << TABS(2) << "_widec = " << CAST(WIDE_ALPH_TYPE()) << "(" << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << "));\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(2) << "if ( "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << " ) _widec += " << condValOffset << ";\n"; } out << " }\n"; out << " break;\n"; } SWITCH_DEFAULT(); out << " }\n"; } void FlatCodeGen::writeExec() { testEofUsed = false; outLabelUsed = false; out << " {\n" " int _slen"; if ( redFsm->anyRegCurStateRef() ) out << ", _ps"; out << ";\n" " int _trans"; if ( redFsm->anyConditions() ) out << ", _cond"; out << ";\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "_acts;\n" " " << UINT() << " _nacts;\n"; } out << " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_keys;\n" " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << PTR_CONST_END() << POINTER() << "_inds;\n"; if ( redFsm->anyConditions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxCond) << PTR_CONST_END() << POINTER() << "_conds;\n" " " << WIDE_ALPH_TYPE() << " _widec;\n"; } out << "\n"; if ( !noEnd ) { testEofUsed = true; out << " if ( " << P() << " == " << PE() << " )\n" " goto _test_eof;\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } out << "_resume:\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << ARR_OFF( A(), FSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; FROM_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyConditions() ) COND_TRANSLATE(); LOCATE_TRANS(); if ( redFsm->anyEofTrans() ) out << "_eof_trans:\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = " << vCS() << ";\n"; out << " " << vCS() << " = " << TT() << "[_trans];\n" "\n"; if ( redFsm->anyRegActions() ) { out << " if ( " << TA() << "[_trans] == 0 )\n" " goto _again;\n" "\n" " _acts = " << ARR_OFF( A(), TA() + "[_trans]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *(_acts++) )\n {\n"; ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->anyRegActions() || redFsm->anyActionGotos() || redFsm->anyActionCalls() || redFsm->anyActionRets() ) out << "_again:\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << ARR_OFF( A(), TSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << CAST(UINT()) << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; TO_STATE_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n" " goto _out;\n"; } if ( !noEnd ) { out << " if ( ++" << P() << " != " << PE() << " )\n" " goto _resume;\n"; } else { out << " " << P() << " += 1;\n" " goto _resume;\n"; } if ( testEofUsed ) out << " _test_eof: {}\n"; if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) { out << " if ( " << P() << " == " << vEOF() << " )\n" " {\n"; if ( redFsm->anyEofTrans() ) { out << " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n" " _trans = " << ET() << "[" << vCS() << "] - 1;\n" " goto _eof_trans;\n" " }\n"; } if ( redFsm->anyEofActions() ) { out << " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << PTR_CONST_END() << POINTER() << "__acts = " << ARR_OFF( A(), EA() + "[" + vCS() + "]" ) << ";\n" " " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n" " while ( __nacts-- > 0 ) {\n" " switch ( *__acts++ ) {\n"; EOF_ACTION_SWITCH(); SWITCH_DEFAULT() << " }\n" " }\n"; } out << " }\n" "\n"; } if ( outLabelUsed ) out << " _out: {}\n"; out << " }\n"; } ragel-6.10/ragel/javacodegen.h0000664000175000017500000001463113065111230013163 00000000000000/* * Copyright 2006-2007 Adrian Thurston * 2007 Colin Fleming */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _JAVACODEGEN_H #define _JAVACODEGEN_H #include #include #include #include "common.h" #include "gendata.h" using std::string; using std::ostream; /* * JavaTabCodeGen */ struct JavaTabCodeGen : public CodeGenData { JavaTabCodeGen( ostream &out ) : CodeGenData(out) {} std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &EOF_ACTION_SWITCH(); std::ostream &ACTION_SWITCH(); std::ostream &COND_KEYS(); std::ostream &COND_SPACES(); std::ostream &KEYS(); std::ostream &INDICIES(); std::ostream &COND_OFFSETS(); std::ostream &KEY_OFFSETS(); std::ostream &INDEX_OFFSETS(); std::ostream &COND_LENS(); std::ostream &SINGLE_LENS(); std::ostream &RANGE_LENS(); std::ostream &TO_STATE_ACTIONS(); std::ostream &FROM_STATE_ACTIONS(); std::ostream &EOF_ACTIONS(); std::ostream &EOF_TRANS(); std::ostream &TRANS_TARGS(); std::ostream &TRANS_ACTIONS(); std::ostream &TRANS_TARGS_WI(); std::ostream &TRANS_ACTIONS_WI(); void BREAK( ostream &ret, int targState ); void GOTO( ostream &ret, int gotoDest, bool inFinish ); void GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); void CALL( ostream &ret, int callDest, int targState, bool inFinish ); void CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ); void RET( ostream &ret, bool inFinish ); void COND_TRANSLATE(); void LOCATE_TRANS(); virtual void writeExec(); virtual void writeData(); virtual void writeInit(); virtual void writeExports(); virtual void writeStart(); virtual void writeFirstFinal(); virtual void writeError(); virtual void finishRagelDef(); void NEXT( ostream &ret, int nextDest, bool inFinish ); void NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ); int TO_STATE_ACTION( RedStateAp *state ); int FROM_STATE_ACTION( RedStateAp *state ); int EOF_ACTION( RedStateAp *state ); int TRANS_ACTION( RedTransAp *trans ); /* Determine if we should use indicies. */ void calcIndexSize(); private: string array_type; string array_name; int item_count; int div_count; public: virtual string NULL_ITEM(); virtual ostream &OPEN_ARRAY( string type, string name ); virtual ostream &ARRAY_ITEM( string item, bool last ); virtual ostream &CLOSE_ARRAY(); virtual ostream &STATIC_VAR( string type, string name ); virtual string ARR_OFF( string ptr, string offset ); virtual string CAST( string type ); virtual string GET_KEY(); virtual string CTRL_FLOW(); string FSM_NAME(); string START_STATE_ID(); ostream &ACTIONS_ARRAY(); string GET_WIDE_KEY(); string GET_WIDE_KEY( RedStateAp *state ); string TABS( int level ); string KEY( Key key ); string INT( int i ); void ACTION( ostream &ret, GenAction *action, int targState, bool inFinish ); void CONDITION( ostream &ret, GenAction *condition ); string ALPH_TYPE(); string WIDE_ALPH_TYPE(); string ARRAY_TYPE( unsigned long maxVal ); string ACCESS(); string P(); string PE(); string vEOF(); string vCS(); string STACK(); string TOP(); string TOKSTART(); string TOKEND(); string ACT(); string DATA(); string DATA_PREFIX(); string PM() { return "_" + DATA_PREFIX() + "partition_map"; } string C() { return "_" + DATA_PREFIX() + "cond_spaces"; } string CK() { return "_" + DATA_PREFIX() + "cond_keys"; } string K() { return "_" + DATA_PREFIX() + "trans_keys"; } string I() { return "_" + DATA_PREFIX() + "indicies"; } string CO() { return "_" + DATA_PREFIX() + "cond_offsets"; } string KO() { return "_" + DATA_PREFIX() + "key_offsets"; } string IO() { return "_" + DATA_PREFIX() + "index_offsets"; } string CL() { return "_" + DATA_PREFIX() + "cond_lengths"; } string SL() { return "_" + DATA_PREFIX() + "single_lengths"; } string RL() { return "_" + DATA_PREFIX() + "range_lengths"; } string A() { return "_" + DATA_PREFIX() + "actions"; } string TA() { return "_" + DATA_PREFIX() + "trans_actions"; } string TT() { return "_" + DATA_PREFIX() + "trans_targs"; } string TSA() { return "_" + DATA_PREFIX() + "to_state_actions"; } string FSA() { return "_" + DATA_PREFIX() + "from_state_actions"; } string EA() { return "_" + DATA_PREFIX() + "eof_actions"; } string ET() { return "_" + DATA_PREFIX() + "eof_trans"; } string SP() { return "_" + DATA_PREFIX() + "key_spans"; } string CSP() { return "_" + DATA_PREFIX() + "cond_key_spans"; } string START() { return DATA_PREFIX() + "start"; } string ERROR() { return DATA_PREFIX() + "error"; } string FIRST_FINAL() { return DATA_PREFIX() + "first_final"; } string CTXDATA() { return DATA_PREFIX() + "ctxdata"; } void INLINE_LIST( ostream &ret, GenInlineList *inlineList, int targState, bool inFinish ); void EXEC( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void EXECTE( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void LM_SWITCH( ostream &ret, GenInlineItem *item, int targState, int inFinish ); void SET_ACT( ostream &ret, GenInlineItem *item ); void INIT_TOKSTART( ostream &ret, GenInlineItem *item ); void INIT_ACT( ostream &ret, GenInlineItem *item ); void SET_TOKSTART( ostream &ret, GenInlineItem *item ); void SET_TOKEND( ostream &ret, GenInlineItem *item ); void GET_TOKEND( ostream &ret, GenInlineItem *item ); void SUB_ACTION( ostream &ret, GenInlineItem *item, int targState, bool inFinish ); string ERROR_STATE(); string FIRST_FINAL_STATE(); ostream &source_warning(const InputLoc &loc); ostream &source_error(const InputLoc &loc); unsigned int arrayTypeSize( unsigned long maxVal ); bool outLabelUsed; bool againLabelUsed; bool useIndicies; void genLineDirective( ostream &out ); }; #endif ragel-6.10/ragel/main.cpp0000664000175000017500000003370513065111230012177 00000000000000/* * Copyright 2001-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #include #include #include #include #if _MSC_VER #define S_IRUSR _S_IREAD #define S_IWUSR _S_IWRITE #endif #endif /* Parsing. */ #include "ragel.h" #include "rlscan.h" /* Parameters and output. */ #include "pcheck.h" #include "vector.h" #include "version.h" #include "common.h" #include "inputdata.h" using std::istream; using std::ostream; using std::ifstream; using std::ofstream; using std::cin; using std::cout; using std::cerr; using std::endl; using std::ios; using std::streamsize; /* Controls minimization. */ MinimizeLevel minimizeLevel = MinimizePartition2; MinimizeOpt minimizeOpt = MinimizeMostOps; /* Graphviz dot file generation. */ const char *machineSpec = 0, *machineName = 0; bool machineSpecFound = false; bool wantDupsRemoved = true; bool printStatistics = false; bool generateXML = false; bool generateDot = false; /* Target language and output style. */ CodeStyle codeStyle = GenTables; int numSplitPartitions = 0; bool noLineDirectives = false; bool displayPrintables = false; /* Target ruby impl */ RubyImplEnum rubyImpl = MRI; /* Print a summary of the options. */ void usage() { cout << "usage: ragel [options] file\n" "general:\n" " -h, -H, -?, --help Print this usage and exit\n" " -v, --version Print version information and exit\n" " -o Write output to \n" " -s Print some statistics on stderr\n" " -d Do not remove duplicates from action lists\n" " -I Add to the list of directories to search\n" " for included an imported files\n" "error reporting format:\n" " --error-format=gnu file:line:column: message (default)\n" " --error-format=msvc file(line,column): message\n" "fsm minimization:\n" " -n Do not perform minimization\n" " -m Minimize at the end of the compilation\n" " -l Minimize after most operations (default)\n" " -e Minimize after every operation\n" "visualization:\n" " -x Run the frontend only: emit XML intermediate format\n" " -V Generate a dot file for Graphviz\n" " -p Display printable characters on labels\n" " -S FSM specification to output (for graphviz output)\n" " -M Machine definition/instantiation to output (for graphviz output)\n" "host language:\n" " -C The host language is C, C++, Obj-C or Obj-C++ (default)\n" " -D The host language is D\n" " -Z The host language is Go\n" " -J The host language is Java\n" " -R The host language is Ruby\n" " -A The host language is C#\n" " -O The host language is OCaml\n" "line directives: (C/D/Ruby/C#/OCaml)\n" " -L Inhibit writing of #line directives\n" "code style: (C/D/Java/Ruby/C#/OCaml)\n" " -T0 Table driven FSM (default)\n" "code style: (C/D/Ruby/C#/OCaml)\n" " -T1 Faster table driven FSM\n" " -F0 Flat table driven FSM\n" " -F1 Faster flat table-driven FSM\n" "code style: (C/D/C#/OCaml)\n" " -G0 Goto-driven FSM\n" " -G1 Faster goto-driven FSM\n" "code style: (C/D)\n" " -G2 Really fast goto-driven FSM\n" " -P N-Way Split really fast goto-driven FSM\n" ; exit(0); } /* Print version information and exit. */ void version() { cout << "Ragel State Machine Compiler version " VERSION << " " PUBDATE << endl << "Copyright (c) 2001-2009 by Adrian Thurston" << endl; exit(0); } /* Error reporting format. */ ErrorFormat errorFormat = ErrorFormatGNU; InputLoc makeInputLoc( const char *fileName, int line, int col) { InputLoc loc = { fileName, line, col }; return loc; } ostream &operator<<( ostream &out, const InputLoc &loc ) { assert( loc.fileName != 0 ); switch ( errorFormat ) { case ErrorFormatMSVC: out << loc.fileName << "(" << loc.line; if ( loc.col ) out << "," << loc.col; out << ")"; break; default: out << loc.fileName << ":" << loc.line; if ( loc.col ) out << ":" << loc.col; break; } return out; } /* Total error count. */ int gblErrorCount = 0; /* Print the opening to a warning in the input, then return the error ostream. */ ostream &warning( const InputLoc &loc ) { cerr << loc << ": warning: "; return cerr; } /* Print the opening to a program error, then return the error stream. */ ostream &error() { gblErrorCount += 1; cerr << PROGNAME ": "; return cerr; } ostream &error( const InputLoc &loc ) { gblErrorCount += 1; cerr << loc << ": "; return cerr; } void escapeLineDirectivePath( std::ostream &out, char *path ) { for ( char *pc = path; *pc != 0; pc++ ) { if ( *pc == '\\' ) out << "\\\\"; else out << *pc; } } void processArgs( int argc, const char **argv, InputData &id ) { ParamCheck pc("xo:dnmleabjkS:M:I:CDEJZRAOvHh?-:sT:F:G:P:LpV", argc, argv); /* FIXME: Need to check code styles VS langauge. */ while ( pc.check() ) { switch ( pc.state ) { case ParamCheck::match: switch ( pc.parameter ) { case 'V': generateDot = true; break; case 'x': generateXML = true; break; /* Output. */ case 'o': if ( *pc.paramArg == 0 ) error() << "a zero length output file name was given" << endl; else if ( id.outputFileName != 0 ) error() << "more than one output file name was given" << endl; else { /* Ok, remember the output file name. */ id.outputFileName = pc.paramArg; } break; /* Flag for turning off duplicate action removal. */ case 'd': wantDupsRemoved = false; break; /* Minimization, mostly hidden options. */ case 'n': minimizeOpt = MinimizeNone; break; case 'm': minimizeOpt = MinimizeEnd; break; case 'l': minimizeOpt = MinimizeMostOps; break; case 'e': minimizeOpt = MinimizeEveryOp; break; case 'a': minimizeLevel = MinimizeApprox; break; case 'b': minimizeLevel = MinimizeStable; break; case 'j': minimizeLevel = MinimizePartition1; break; case 'k': minimizeLevel = MinimizePartition2; break; /* Machine spec. */ case 'S': if ( *pc.paramArg == 0 ) error() << "please specify an argument to -S" << endl; else if ( machineSpec != 0 ) error() << "more than one -S argument was given" << endl; else { /* Ok, remember the path to the machine to generate. */ machineSpec = pc.paramArg; } break; /* Machine path. */ case 'M': if ( *pc.paramArg == 0 ) error() << "please specify an argument to -M" << endl; else if ( machineName != 0 ) error() << "more than one -M argument was given" << endl; else { /* Ok, remember the machine name to generate. */ machineName = pc.paramArg; } break; case 'I': if ( *pc.paramArg == 0 ) error() << "please specify an argument to -I" << endl; else { id.includePaths.append( pc.paramArg ); } break; /* Host language types. */ case 'C': hostLang = &hostLangC; break; case 'D': hostLang = &hostLangD; break; case 'E': hostLang = &hostLangD2; break; case 'Z': hostLang = &hostLangGo; break; case 'J': hostLang = &hostLangJava; break; case 'R': hostLang = &hostLangRuby; break; case 'A': hostLang = &hostLangCSharp; break; case 'O': hostLang = &hostLangOCaml; break; /* Version and help. */ case 'v': version(); break; case 'H': case 'h': case '?': usage(); break; case 's': printStatistics = true; break; case '-': { char *arg = strdup( pc.paramArg ); char *eq = strchr( arg, '=' ); if ( eq != 0 ) *eq++ = 0; if ( strcmp( arg, "help" ) == 0 ) usage(); else if ( strcmp( arg, "version" ) == 0 ) version(); else if ( strcmp( arg, "error-format" ) == 0 ) { if ( eq == 0 ) error() << "expecting '=value' for error-format" << endl; else if ( strcmp( eq, "gnu" ) == 0 ) errorFormat = ErrorFormatGNU; else if ( strcmp( eq, "msvc" ) == 0 ) errorFormat = ErrorFormatMSVC; else error() << "invalid value for error-format" << endl; } else if ( strcmp( arg, "rbx" ) == 0 ) rubyImpl = Rubinius; else { error() << "--" << pc.paramArg << " is an invalid argument" << endl; } free( arg ); break; } /* Passthrough args. */ case 'T': if ( pc.paramArg[0] == '0' ) codeStyle = GenTables; else if ( pc.paramArg[0] == '1' ) codeStyle = GenFTables; else { error() << "-T" << pc.paramArg[0] << " is an invalid argument" << endl; exit(1); } break; case 'F': if ( pc.paramArg[0] == '0' ) codeStyle = GenFlat; else if ( pc.paramArg[0] == '1' ) codeStyle = GenFFlat; else { error() << "-F" << pc.paramArg[0] << " is an invalid argument" << endl; exit(1); } break; case 'G': if ( pc.paramArg[0] == '0' ) codeStyle = GenGoto; else if ( pc.paramArg[0] == '1' ) codeStyle = GenFGoto; else if ( pc.paramArg[0] == '2' ) codeStyle = GenIpGoto; else { error() << "-G" << pc.paramArg[0] << " is an invalid argument" << endl; exit(1); } break; case 'P': codeStyle = GenSplit; numSplitPartitions = atoi( pc.paramArg ); break; case 'p': displayPrintables = true; break; case 'L': noLineDirectives = true; break; } break; case ParamCheck::invalid: error() << "-" << pc.parameter << " is an invalid argument" << endl; break; case ParamCheck::noparam: /* It is interpreted as an input file. */ if ( *pc.curArg == 0 ) error() << "a zero length input file name was given" << endl; else if ( id.inputFileName != 0 ) error() << "more than one input file name was given" << endl; else { /* OK, Remember the filename. */ id.inputFileName = pc.curArg; } break; } } } void process( InputData &id ) { /* Open the input file for reading. */ assert( id.inputFileName != 0 ); ifstream *inFile = new ifstream( id.inputFileName ); if ( ! inFile->is_open() ) error() << "could not open " << id.inputFileName << " for reading" << endp; /* Used for just a few things. */ std::ostringstream hostData; /* Make the first input item. */ InputItem *firstInputItem = new InputItem; firstInputItem->type = InputItem::HostData; firstInputItem->loc.fileName = id.inputFileName; firstInputItem->loc.line = 1; firstInputItem->loc.col = 1; id.inputItems.append( firstInputItem ); Scanner scanner( id, id.inputFileName, *inFile, 0, 0, 0, false ); scanner.do_scan(); /* Finished, final check for errors.. */ if ( gblErrorCount > 0 ) exit(1); /* Now send EOF to all parsers. */ id.terminateAllParsers(); /* Bail on above error. */ if ( gblErrorCount > 0 ) exit(1); /* Locate the backend program */ /* Compiles machines. */ id.prepareMachineGen(); if ( gblErrorCount > 0 ) exit(1); id.makeOutputStream(); /* Generates the reduced machine, which we use to write output. */ if ( !generateXML ) { id.generateReduced(); if ( gblErrorCount > 0 ) exit(1); } id.verifyWritesHaveData(); if ( gblErrorCount > 0 ) exit(1); /* * From this point on we should not be reporting any errors. */ id.openOutput(); id.writeOutput(); /* Close the input and the intermediate file. */ delete inFile; /* If writing to a file, delete the ostream, causing it to flush. * Standard out is flushed automatically. */ if ( id.outputFileName != 0 ) { delete id.outStream; delete id.outFilter; } assert( gblErrorCount == 0 ); } char *makeIntermedTemplate( const char *baseFileName ) { char *result = 0; const char *templ = "ragel-XXXXXX.xml"; const char *lastSlash = strrchr( baseFileName, '/' ); if ( lastSlash == 0 ) { result = new char[strlen(templ)+1]; strcpy( result, templ ); } else { int baseLen = lastSlash - baseFileName + 1; result = new char[baseLen + strlen(templ) + 1]; memcpy( result, baseFileName, baseLen ); strcpy( result+baseLen, templ ); } return result; }; /* Main, process args and call yyparse to start scanning input. */ int main( int argc, const char **argv ) { InputData id; processArgs( argc, argv, id ); /* Require an input file. If we use standard in then we won't have a file * name on which to base the output. */ if ( id.inputFileName == 0 ) error() << "no input file given" << endl; /* Bail on argument processing errors. */ if ( gblErrorCount > 0 ) exit(1); /* Make sure we are not writing to the same file as the input file. */ if ( id.inputFileName != 0 && id.outputFileName != 0 && strcmp( id.inputFileName, id.outputFileName ) == 0 ) { error() << "output file \"" << id.outputFileName << "\" is the same as the input file" << endp; } process( id ); return 0; } ragel-6.10/ragel/rbxgoto.cpp0000664000175000017500000005306313065111230012736 00000000000000/* * Copyright 2007 Victor Hugo Borja * 2006-2007 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "rbxgoto.h" #include "ragel.h" #include "redfsm.h" #include "bstmap.h" #include "gendata.h" using std::ostream; using std::string; inline string label(string a, int i) { return a + itoa(i); } ostream &RbxGotoCodeGen::rbxLabel(ostream &out, string label) { out << "Rubinius.asm { @labels[:_" << FSM_NAME() << "_" << label << "].set! }\n"; return out; } ostream &RbxGotoCodeGen::rbxGoto(ostream &out, string label) { out << "Rubinius.asm { goto @labels[:_" << FSM_NAME() << "_" << label << "] }\n"; return out; } /* Emit the goto to take for a given transition. */ std::ostream &RbxGotoCodeGen::TRANS_GOTO( RedTransAp *trans, int level ) { out << TABS(level); return rbxGoto(out, label("tr",trans->id)); } std::ostream &RbxGotoCodeGen::TO_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numToStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RbxGotoCodeGen::FROM_STATE_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numFromStateRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } std::ostream &RbxGotoCodeGen::EOF_ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numEofRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, true ); } } genLineDirective( out ); return out; } std::ostream &RbxGotoCodeGen::ACTION_SWITCH() { /* Walk the list of functions, printing the cases. */ for ( GenActionList::Iter act = actionList; act.lte(); act++ ) { /* Write out referenced actions. */ if ( act->numTransRefs > 0 ) { /* Write the case label, the action and the case break. */ out << "\twhen " << act->actionId << " then\n"; ACTION( out, act, 0, false ); } } genLineDirective( out ); return out; } void RbxGotoCodeGen::GOTO_HEADER( RedStateAp *state ) { /* Label the state. */ out << "when " << state->id << " then\n"; } void RbxGotoCodeGen::emitSingleSwitch( RedStateAp *state ) { /* Load up the singles. */ int numSingles = state->outSingle.length(); RedTransEl *data = state->outSingle.data; if ( numSingles == 1 ) { /* If there is a single single key then write it out as an if. */ out << "\tif " << GET_WIDE_KEY(state) << " == " << KEY(data[0].lowKey) << " \n\t\t"; /* Virtual function for writing the target of the transition. */ TRANS_GOTO(data[0].value, 0) << "\n"; out << "end\n"; } else if ( numSingles > 1 ) { /* Write out single keys in a switch if there is more than one. */ out << "\tcase " << GET_WIDE_KEY(state) << "\n"; /* Write out the single indicies. */ for ( int j = 0; j < numSingles; j++ ) { out << "\t\twhen " << KEY(data[j].lowKey) << " then\n"; TRANS_GOTO(data[j].value, 0) << "\n"; } /* Close off the transition switch. */ out << "\tend\n"; } } void RbxGotoCodeGen::emitRangeBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; RedTransEl *data = state->outRange.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid].lowKey == keyOps->minKey; bool limitHigh = data[mid].highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if " << GET_WIDE_KEY(state) << " < " << KEY(data[mid].lowKey) << " \n"; emitRangeBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "elsif " << GET_WIDE_KEY(state) << " > " << KEY(data[mid].highKey) << " \n"; emitRangeBSearch( state, level+1, mid+1, high ); out << TABS(level) << "else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; out << TABS(level) << "end\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if " << GET_WIDE_KEY(state) << " < " << KEY(data[mid].lowKey) << " then\n"; emitRangeBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << "elsif" << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " )\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } out << TABS(level) << "end\n"; } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if " << GET_WIDE_KEY(state) << " > " << KEY(data[mid].highKey) << " \n"; emitRangeBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "else\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } else { out << TABS(level) << "elsif " << GET_WIDE_KEY(state) << " >= " << KEY(data[mid].lowKey) << " then\n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; } out << TABS(level) << "end\n"; } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if " << KEY(data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " && " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " \n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; out << TABS(level) << "end\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if " << GET_WIDE_KEY(state) << " <= " << KEY(data[mid].highKey) << " \n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; out << TABS(level) << "end\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if " << KEY(data[mid].lowKey) << " <= " << GET_WIDE_KEY(state) << " \n"; TRANS_GOTO(data[mid].value, level+1) << "\n"; out << TABS(level) << "end\n"; } else { /* Both high and low are at the limit. No tests to do. */ TRANS_GOTO(data[mid].value, level+1) << "\n"; } } } void RbxGotoCodeGen::STATE_GOTO_ERROR() { /* Label the state and bail immediately. */ outLabelUsed = true; RedStateAp *state = redFsm->errState; out << "when " << state->id << " then\n"; rbxGoto(out << " ", "_out") << "\n"; } void RbxGotoCodeGen::COND_TRANSLATE( GenStateCond *stateCond, int level ) { GenCondSpace *condSpace = stateCond->condSpace; out << TABS(level) << "_widec = " << KEY(condSpace->baseKey) << " + (" << GET_KEY() << " - " << KEY(keyOps->minKey) << ");\n"; for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) { out << TABS(level) << "if "; CONDITION( out, *csi ); Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize()); out << "\n _widec += " << condValOffset << ";\n end"; } } void RbxGotoCodeGen::emitCondBSearch( RedStateAp *state, int level, int low, int high ) { /* Get the mid position, staying on the lower end of the range. */ int mid = (low + high) >> 1; GenStateCond **data = state->stateCondVect.data; /* Determine if we need to look higher or lower. */ bool anyLower = mid > low; bool anyHigher = mid < high; /* Determine if the keys at mid are the limits of the alphabet. */ bool limitLow = data[mid]->lowKey == keyOps->minKey; bool limitHigh = data[mid]->highKey == keyOps->maxKey; if ( anyLower && anyHigher ) { /* Can go lower and higher than mid. */ out << TABS(level) << "if " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " \n"; emitCondBSearch( state, level+1, low, mid-1 ); out << TABS(level) << "elsif " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " \n"; emitCondBSearch( state, level+1, mid+1, high ); out << TABS(level) << "else\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "end\n"; } else if ( anyLower && !anyHigher ) { /* Can go lower than mid but not higher. */ out << TABS(level) << "if " << GET_KEY() << " < " << KEY(data[mid]->lowKey) << " \n"; emitCondBSearch( state, level+1, low, mid-1 ); /* if the higher is the highest in the alphabet then there is no * sense testing it. */ if ( limitHigh ) { out << TABS(level) << "else\n"; COND_TRANSLATE(data[mid], level+1); } else { out << TABS(level) << "elsif " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " then\n"; COND_TRANSLATE(data[mid], level+1); } out << TABS(level) << "end\n"; } else if ( !anyLower && anyHigher ) { /* Can go higher than mid but not lower. */ out << TABS(level) << "if " << GET_KEY() << " > " << KEY(data[mid]->highKey) << " \n"; emitCondBSearch( state, level+1, mid+1, high ); /* If the lower end is the lowest in the alphabet then there is no * sense testing it. */ if ( limitLow ) { out << TABS(level) << "else\n"; COND_TRANSLATE(data[mid], level+1); } else { out << TABS(level) << "elsif " << GET_KEY() << " >= " << KEY(data[mid]->lowKey) << " then\n"; COND_TRANSLATE(data[mid], level+1); } out << TABS(level) << "end\n"; } else { /* Cannot go higher or lower than mid. It's mid or bust. What * tests to do depends on limits of alphabet. */ if ( !limitLow && !limitHigh ) { out << TABS(level) << "if " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " && " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " then\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "end\n"; } else if ( limitLow && !limitHigh ) { out << TABS(level) << "if " << GET_KEY() << " <= " << KEY(data[mid]->highKey) << " then\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "end\n"; } else if ( !limitLow && limitHigh ) { out << TABS(level) << "if " << KEY(data[mid]->lowKey) << " <= " << GET_KEY() << " then\n"; COND_TRANSLATE(data[mid], level+1); out << TABS(level) << "end\n"; } else { /* Both high and low are at the limit. No tests to do. */ COND_TRANSLATE(data[mid], level); } } } std::ostream &RbxGotoCodeGen::STATE_GOTOS() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { if ( st == redFsm->errState ) STATE_GOTO_ERROR(); else { /* Writing code above state gotos. */ GOTO_HEADER( st ); if ( st->stateCondVect.length() > 0 ) { out << " _widec = " << GET_KEY() << ";\n"; emitCondBSearch( st, 1, 0, st->stateCondVect.length() - 1 ); } /* Try singles. */ if ( st->outSingle.length() > 0 ) emitSingleSwitch( st ); /* Default case is to binary search for the ranges, if that fails then */ if ( st->outRange.length() > 0 ) emitRangeBSearch( st, 1, 0, st->outRange.length() - 1 ); /* Write the default transition. */ TRANS_GOTO( st->defTrans, 1 ) << "\n"; } } return out; } std::ostream &RbxGotoCodeGen::TRANSITIONS() { /* Emit any transitions that have functions and that go to * this state. */ for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) { /* Write the label for the transition so it can be jumped to. */ rbxLabel(out << " ", label("tr", trans->id)) << "\n"; /* Destination state. */ if ( trans->action != 0 && trans->action->anyCurStateRef() ) out << "_ps = " << vCS() << "'n"; out << vCS() << " = " << trans->targ->id << "\n"; if ( trans->action != 0 ) { /* Write out the transition func. */ rbxGoto(out, label("f", trans->action->actListId)) << "\n"; } else { /* No code to execute, just loop around. */ rbxGoto(out, "_again") << "\n"; } } return out; } std::ostream &RbxGotoCodeGen::EXEC_FUNCS() { /* Make labels that set acts and jump to execFuncs. Loop func indicies. */ for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { if ( redAct->numTransRefs > 0 ) { rbxLabel(out, label("f", redAct->actListId)) << "\n" << "_acts = " << itoa( redAct->location+1 ) << "\n"; rbxGoto(out, "execFuncs") << "\n"; } } rbxLabel(out, "execFuncs") << "\n" " _nacts = " << A() << "[_acts]\n" " _acts += 1\n" " while ( _nacts > 0 ) \n" " _nacts -= 1\n" " _acts += 1\n" " case ( "<< A() << "[_acts-1] ) \n"; ACTION_SWITCH(); out << " end\n" " end \n"; rbxGoto(out, "_again"); return out; } int RbxGotoCodeGen::TO_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->toStateAction != 0 ) act = state->toStateAction->location+1; return act; } int RbxGotoCodeGen::FROM_STATE_ACTION( RedStateAp *state ) { int act = 0; if ( state->fromStateAction != 0 ) act = state->fromStateAction->location+1; return act; } int RbxGotoCodeGen::EOF_ACTION( RedStateAp *state ) { int act = 0; if ( state->eofAction != 0 ) act = state->eofAction->location+1; return act; } std::ostream &RbxGotoCodeGen::TO_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = TO_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &RbxGotoCodeGen::FROM_STATE_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = FROM_STATE_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &RbxGotoCodeGen::EOF_ACTIONS() { /* Take one off for the psuedo start state. */ int numStates = redFsm->stateList.length(); unsigned int *vals = new unsigned int[numStates]; memset( vals, 0, sizeof(unsigned int)*numStates ); for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) vals[st->id] = EOF_ACTION(st); out << "\t"; for ( int st = 0; st < redFsm->nextStateId; st++ ) { /* Write any eof action. */ out << vals[st]; if ( st < numStates-1 ) { out << ", "; if ( (st+1) % IALL == 0 ) out << "\n\t"; } } out << "\n"; delete[] vals; return out; } std::ostream &RbxGotoCodeGen::FINISH_CASES() { for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { /* States that are final and have an out action need a case. */ if ( st->eofAction != 0 ) { /* Write the case label. */ out << "\t\twhen " << st->id << " then\n"; /* Write the goto func. */ rbxGoto(out, label("f", st->eofAction->actListId)) << "\n"; } } return out; } void RbxGotoCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) { ret << "begin\n" << vCS() << " = " << gotoDest << " "; rbxGoto(ret, "_again") << "\nend\n"; } void RbxGotoCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << "begin\n" << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ")"; rbxGoto(ret, "_again") << "\nend\n"; } void RbxGotoCodeGen::CURS( ostream &ret, bool inFinish ) { ret << "(_ps)"; } void RbxGotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState ) { ret << "(" << vCS() << ")"; } void RbxGotoCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) { ret << vCS() << " = " << nextDest << ";"; } void RbxGotoCodeGen::NEXT_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) { ret << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, 0, inFinish ); ret << ");"; } void RbxGotoCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin\n" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = " << callDest << "; "; rbxGoto(ret, "_again") << "\nend\n"; if ( prePushExpr != 0 ) ret << "}"; } void RbxGotoCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) { if ( prePushExpr != 0 ) { ret << "{"; INLINE_LIST( ret, prePushExpr, 0, false ); } ret << "begin\n" << STACK() << "[" << TOP() << "++] = " << vCS() << "; " << vCS() << " = ("; INLINE_LIST( ret, ilItem->children, targState, inFinish ); ret << "); "; rbxGoto(ret, "_again") << "\nend\n"; if ( prePushExpr != 0 ) ret << "}"; } void RbxGotoCodeGen::RET( ostream &ret, bool inFinish ) { ret << "begin\n" << vCS() << " = " << STACK() << "[--" << TOP() << "]; " ; if ( postPopExpr != 0 ) { ret << "{"; INLINE_LIST( ret, postPopExpr, 0, false ); ret << "}"; } rbxGoto(ret, "_again") << "\nend\n"; } void RbxGotoCodeGen::BREAK( ostream &ret, int targState ) { outLabelUsed = true; out << " begin\n" " " << P() << " += 1\n" " "; rbxGoto(ret, "_out") << "\n" " end\n"; } void RbxGotoCodeGen::writeData() { if ( redFsm->anyActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() ); ACTIONS_ARRAY(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyToStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() ); TO_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyFromStateActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() ); FROM_STATE_ACTIONS(); CLOSE_ARRAY() << "\n"; } if ( redFsm->anyEofActions() ) { OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() ); EOF_ACTIONS(); CLOSE_ARRAY() << "\n"; } STATE_IDS(); } void RbxGotoCodeGen::writeExec() { outLabelUsed = false; out << " begin\n"; out << " Rubinius.asm { @labels = Hash.new { |h,k| h[k] = new_label } }\n"; if ( redFsm->anyRegCurStateRef() ) out << " _ps = 0;\n"; if ( redFsm->anyToStateActions() || redFsm->anyRegActions() || redFsm->anyFromStateActions() ) { out << " _acts, _nacts = nil\n"; } if ( redFsm->anyConditions() ) out << " _widec = nil\n"; out << "\n"; if ( !noEnd ) { outLabelUsed = true; out << " if ( " << P() << " == " << PE() << " )\n"; rbxGoto(out << " ", "_out") << "\n" << " end\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n"; rbxGoto(out << " ", "_out") << "\n" << " end\n"; } rbxLabel(out, "_resume") << "\n"; if ( redFsm->anyFromStateActions() ) { out << " _acts = " << ARR_OFF( A(), FSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; FROM_STATE_ACTION_SWITCH(); out << " }\n" " }\n" "\n"; } out << " case ( " << vCS() << " )\n"; STATE_GOTOS(); out << " end # case\n" "\n"; TRANSITIONS() << "\n"; if ( redFsm->anyRegActions() ) EXEC_FUNCS() << "\n"; rbxLabel(out, "_again") << "\n"; if ( redFsm->anyToStateActions() ) { out << " _acts = " << ARR_OFF( A(), TSA() + "[" + vCS() + "]" ) << ";\n" " _nacts = " << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; TO_STATE_ACTION_SWITCH(); out << " }\n" " }\n" "\n"; } if ( redFsm->errState != 0 ) { outLabelUsed = true; out << " if ( " << vCS() << " == " << redFsm->errState->id << " )\n"; rbxGoto(out << " ", "_out") << "\n" << " end" << "\n"; } if ( !noEnd ) { out << " " << P() << " += 1\n" " if ( " << P() << " != " << PE() << " )\n"; rbxGoto(out << " ", "_resume") << "\n" << " end" << "\n"; } else { out << " " << P() << " += 1;\n"; rbxGoto(out << " ", "_resume") << "\n"; } if ( outLabelUsed ) rbxLabel(out, "_out") << "\n"; out << " end\n"; } void RbxGotoCodeGen::writeEOF() { if ( redFsm->anyEofActions() ) { out << " {\n" " _acts = " << ARR_OFF( A(), EA() + "[" + vCS() + "]" ) << ";\n" " " << " _nacts = " << " *_acts++;\n" " while ( _nacts-- > 0 ) {\n" " switch ( *_acts++ ) {\n"; EOF_ACTION_SWITCH(); out << " }\n" " }\n" " }\n" "\n"; } } /* * Local Variables: * mode: c++ * indent-tabs-mode: 1 * c-file-style: "bsd" * End: */ ragel-6.10/ragel/mlfgoto.h0000664000175000017500000000306013065111230012356 00000000000000/* * Copyright 2001-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MLFGOTO_H #define _MLFGOTO_H #include #include "mlgoto.h" /* * class OCamlFGotoCodeGen */ class OCamlFGotoCodeGen : virtual public OCamlGotoCodeGen { public: OCamlFGotoCodeGen( ostream &out ) : OCamlCodeGen(out), OCamlGotoCodeGen(out) {} std::ostream &EXEC_ACTIONS(); std::ostream &TO_STATE_ACTION_SWITCH(); std::ostream &FROM_STATE_ACTION_SWITCH(); std::ostream &FINISH_CASES(); std::ostream &EOF_ACTION_SWITCH(); unsigned int TO_STATE_ACTION( RedStateAp *state ); unsigned int FROM_STATE_ACTION( RedStateAp *state ); unsigned int EOF_ACTION( RedStateAp *state ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/gofflat.h0000664000175000017500000000322213065111230012331 00000000000000/* * Copyright 2004-2006 Adrian Thurston * 2004 Erich Ocean * 2005 Alan West */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOFFLAT_H #define _GOFFLAT_H #include #include "goflat.h" /* Forwards. */ struct CodeGenData; /* * FFlatCodeGen */ class GoFFlatCodeGen : public GoFlatCodeGen { public: GoFFlatCodeGen( ostream &out ) : GoFlatCodeGen(out) {} protected: std::ostream &TO_STATE_ACTION_SWITCH( int level ); std::ostream &FROM_STATE_ACTION_SWITCH( int level ); std::ostream &EOF_ACTION_SWITCH( int level ); std::ostream &ACTION_SWITCH( int level ); virtual std::ostream &TO_STATE_ACTION( RedStateAp *state ); virtual std::ostream &FROM_STATE_ACTION( RedStateAp *state ); virtual std::ostream &EOF_ACTION( RedStateAp *state ); virtual std::ostream &TRANS_ACTION( RedTransAp *trans ); virtual void writeData(); virtual void writeExec(); }; #endif ragel-6.10/ragel/rlscan.cpp0000664000175000017500000041737413065122655012562 00000000000000 #line 1 "rlscan.rl" /* * Copyright 2006-2007 Adrian Thurston * Copyright 2011 Josef Goettgens */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "ragel.h" #include "rlscan.h" #include "inputdata.h" //#define LOG_TOKENS using std::ifstream; using std::istream; using std::ostream; using std::cout; using std::cerr; using std::endl; enum InlineBlockType { CurlyDelimited, SemiTerminated }; #ifdef _WIN32 #define PATH_SEP '\\' #else #define PATH_SEP '/' #endif /* * The Scanner for Importing */ #line 125 "rlscan.rl" #line 65 "rlscan.cpp" static const int inline_token_scan_start = 2; static const int inline_token_scan_first_final = 2; static const int inline_token_scan_error = -1; static const int inline_token_scan_en_main = 2; #line 128 "rlscan.rl" void Scanner::flushImport() { int *p = token_data; int *pe = token_data + cur_token; int *eof = 0; #line 82 "rlscan.cpp" { tok_cs = inline_token_scan_start; tok_ts = 0; tok_te = 0; tok_act = 0; } #line 90 "rlscan.cpp" { if ( p == pe ) goto _test_eof; switch ( tok_cs ) { tr0: #line 123 "rlscan.rl" {{p = (( tok_te))-1;}} goto st2; tr1: #line 109 "rlscan.rl" { tok_te = p+1;{ int base = tok_ts - token_data; int nameOff = 0; int litOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_Literal, token_strings[base+litOff], token_lens[base+litOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }} goto st2; tr2: #line 81 "rlscan.rl" { tok_te = p+1;{ int base = tok_ts - token_data; int nameOff = 0; int numOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_UInt, token_strings[base+numOff], token_lens[base+numOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }} goto st2; tr3: #line 95 "rlscan.rl" { tok_te = p+1;{ int base = tok_ts - token_data; int nameOff = 1; int litOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_Literal, token_strings[base+litOff], token_lens[base+litOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }} goto st2; tr4: #line 67 "rlscan.rl" { tok_te = p+1;{ int base = tok_ts - token_data; int nameOff = 1; int numOff = 2; directToParser( inclToParser, fileName, line, column, TK_Word, token_strings[base+nameOff], token_lens[base+nameOff] ); directToParser( inclToParser, fileName, line, column, '=', 0, 0 ); directToParser( inclToParser, fileName, line, column, TK_UInt, token_strings[base+numOff], token_lens[base+numOff] ); directToParser( inclToParser, fileName, line, column, ';', 0, 0 ); }} goto st2; tr5: #line 123 "rlscan.rl" { tok_te = p+1;} goto st2; tr8: #line 123 "rlscan.rl" { tok_te = p;p--;} goto st2; st2: #line 1 "NONE" { tok_ts = 0;} if ( ++p == pe ) goto _test_eof2; case 2: #line 1 "NONE" { tok_ts = p;} #line 176 "rlscan.cpp" switch( (*p) ) { case 128: goto tr6; case 131: goto tr7; } goto tr5; tr6: #line 1 "NONE" { tok_te = p+1;} goto st3; st3: if ( ++p == pe ) goto _test_eof3; case 3: #line 190 "rlscan.cpp" if ( (*p) == 61 ) goto st0; goto tr8; st0: if ( ++p == pe ) goto _test_eof0; case 0: switch( (*p) ) { case 129: goto tr1; case 130: goto tr2; } goto tr0; tr7: #line 1 "NONE" { tok_te = p+1;} goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: #line 211 "rlscan.cpp" if ( (*p) == 128 ) goto st1; goto tr8; st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 129: goto tr3; case 130: goto tr4; } goto tr0; } _test_eof2: tok_cs = 2; goto _test_eof; _test_eof3: tok_cs = 3; goto _test_eof; _test_eof0: tok_cs = 0; goto _test_eof; _test_eof4: tok_cs = 4; goto _test_eof; _test_eof1: tok_cs = 1; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( tok_cs ) { case 3: goto tr8; case 0: goto tr0; case 4: goto tr8; case 1: goto tr0; } } } #line 139 "rlscan.rl" if ( tok_ts == 0 ) cur_token = 0; else { cur_token = pe - tok_ts; int ts_offset = tok_ts - token_data; memmove( token_data, token_data+ts_offset, cur_token*sizeof(token_data[0]) ); memmove( token_strings, token_strings+ts_offset, cur_token*sizeof(token_strings[0]) ); memmove( token_lens, token_lens+ts_offset, cur_token*sizeof(token_lens[0]) ); } } void Scanner::directToParser( Parser *toParser, const char *tokFileName, int tokLine, int tokColumn, int type, char *tokdata, int toklen ) { InputLoc loc; #ifdef LOG_TOKENS cerr << "scanner:" << tokLine << ":" << tokColumn << ": sending token to the parser " << Parser_lelNames[type]; cerr << " " << toklen; if ( tokdata != 0 ) cerr << " " << tokdata; cerr << endl; #endif loc.fileName = tokFileName; loc.line = tokLine; loc.col = tokColumn; toParser->token( loc, type, tokdata, toklen ); } void Scanner::importToken( int token, char *start, char *end ) { if ( cur_token == max_tokens ) flushImport(); token_data[cur_token] = token; if ( start == 0 ) { token_strings[cur_token] = 0; token_lens[cur_token] = 0; } else { int toklen = end-start; token_lens[cur_token] = toklen; token_strings[cur_token] = new char[toklen+1]; memcpy( token_strings[cur_token], start, toklen ); token_strings[cur_token][toklen] = 0; } cur_token++; } void Scanner::pass( int token, char *start, char *end ) { if ( importMachines ) importToken( token, start, end ); pass(); } void Scanner::pass() { updateCol(); /* If no errors and we are at the bottom of the include stack (the * source file listed on the command line) then write out the data. */ if ( includeDepth == 0 && machineSpec == 0 && machineName == 0 ) id.inputItems.tail->data.write( ts, te-ts ); } /* * The scanner for processing sections, includes, imports, etc. */ #line 321 "rlscan.cpp" static const int section_parse_start = 10; static const int section_parse_first_final = 10; static const int section_parse_error = 0; static const int section_parse_en_main = 10; #line 218 "rlscan.rl" void Scanner::init( ) { #line 336 "rlscan.cpp" { cs = section_parse_start; } #line 224 "rlscan.rl" } bool Scanner::active() { if ( ignoreSection ) return false; if ( parser == 0 && ! parserExistsError ) { scan_error() << "this specification has no name, nor does any previous" " specification" << endl; parserExistsError = true; } if ( parser == 0 ) return false; return true; } ostream &Scanner::scan_error() { /* Maintain the error count. */ gblErrorCount += 1; cerr << makeInputLoc( fileName, line, column ) << ": "; return cerr; } /* An approximate check for duplicate includes. Due to aliasing of files it's * possible for duplicates to creep in. */ bool Scanner::duplicateInclude( char *inclFileName, char *inclSectionName ) { for ( IncludeHistory::Iter hi = parser->includeHistory; hi.lte(); hi++ ) { if ( strcmp( hi->fileName, inclFileName ) == 0 && strcmp( hi->sectionName, inclSectionName ) == 0 ) { return true; } } return false; } void Scanner::updateCol() { char *from = lastnl; if ( from == 0 ) from = ts; //cerr << "adding " << te - from << " to column" << endl; column += te - from; lastnl = 0; } void Scanner::handleMachine() { /* Assign a name to the machine. */ char *machine = word; if ( !importMachines && inclSectionTarg == 0 ) { ignoreSection = false; ParserDictEl *pdEl = id.parserDict.find( machine ); if ( pdEl == 0 ) { pdEl = new ParserDictEl( machine ); pdEl->value = new Parser( fileName, machine, sectionLoc ); pdEl->value->init(); id.parserDict.insert( pdEl ); id.parserList.append( pdEl->value ); } parser = pdEl->value; } else if ( !importMachines && strcmp( inclSectionTarg, machine ) == 0 ) { /* found include target */ ignoreSection = false; parser = inclToParser; } else { /* ignoring section */ ignoreSection = true; parser = 0; } } void Scanner::handleInclude() { if ( active() ) { char *inclSectionName = word; char **includeChecks = 0; /* Implement defaults for the input file and section name. */ if ( inclSectionName == 0 ) inclSectionName = parser->sectionName; if ( lit != 0 ) includeChecks = makeIncludePathChecks( fileName, lit, lit_len ); else { char *test = new char[strlen(fileName)+1]; strcpy( test, fileName ); includeChecks = new char*[2]; includeChecks[0] = test; includeChecks[1] = 0; } long found = 0; ifstream *inFile = tryOpenInclude( includeChecks, found ); if ( inFile == 0 ) { scan_error() << "include: failed to locate file" << endl; char **tried = includeChecks; while ( *tried != 0 ) scan_error() << "include: attempted: \"" << *tried++ << '\"' << endl; } else { /* Don't include anything that's already been included. */ if ( !duplicateInclude( includeChecks[found], inclSectionName ) ) { parser->includeHistory.append( IncludeHistoryItem( includeChecks[found], inclSectionName ) ); Scanner scanner( id, includeChecks[found], *inFile, parser, inclSectionName, includeDepth+1, false ); scanner.do_scan( ); delete inFile; } } } } void Scanner::handleImport() { if ( active() ) { char **importChecks = makeIncludePathChecks( fileName, lit, lit_len ); /* Open the input file for reading. */ long found = 0; ifstream *inFile = tryOpenInclude( importChecks, found ); if ( inFile == 0 ) { scan_error() << "import: could not open import file " << "for reading" << endl; char **tried = importChecks; while ( *tried != 0 ) scan_error() << "import: attempted: \"" << *tried++ << '\"' << endl; } Scanner scanner( id, importChecks[found], *inFile, parser, 0, includeDepth+1, true ); scanner.do_scan( ); scanner.importToken( 0, 0, 0 ); scanner.flushImport(); delete inFile; } } #line 461 "rlscan.rl" void Scanner::token( int type, char c ) { token( type, &c, &c + 1 ); } void Scanner::token( int type ) { token( type, 0, 0 ); } void Scanner::token( int type, char *start, char *end ) { char *tokdata = 0; int toklen = 0; if ( start != 0 ) { toklen = end-start; tokdata = new char[toklen+1]; memcpy( tokdata, start, toklen ); tokdata[toklen] = 0; } processToken( type, tokdata, toklen ); } void Scanner::processToken( int type, char *tokdata, int toklen ) { int *p, *pe, *eof; if ( type < 0 ) p = pe = eof = 0; else { p = &type; pe = &type + 1; eof = 0; } #line 535 "rlscan.cpp" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr2: #line 391 "rlscan.rl" { handleMachine(); } goto st10; tr6: #line 392 "rlscan.rl" { handleInclude(); } goto st10; tr10: #line 393 "rlscan.rl" { handleImport(); } goto st10; tr13: #line 433 "rlscan.rl" { if ( active() && machineSpec == 0 && machineName == 0 ) id.inputItems.tail->writeArgs.append( 0 ); } goto st10; tr14: #line 444 "rlscan.rl" { /* Send the token off to the parser. */ if ( active() ) directToParser( parser, fileName, line, column, type, tokdata, toklen ); } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: #line 572 "rlscan.cpp" switch( (*p) ) { case 191: goto st1; case 192: goto st3; case 193: goto st6; case 194: goto tr18; } goto tr14; st1: if ( ++p == pe ) goto _test_eof1; case 1: if ( (*p) == 128 ) goto tr1; goto tr0; tr0: #line 386 "rlscan.rl" { scan_error() << "bad machine statement" << endl; } goto st0; tr3: #line 387 "rlscan.rl" { scan_error() << "bad include statement" << endl; } goto st0; tr8: #line 388 "rlscan.rl" { scan_error() << "bad import statement" << endl; } goto st0; tr11: #line 389 "rlscan.rl" { scan_error() << "bad write statement" << endl; } goto st0; #line 603 "rlscan.cpp" st0: cs = 0; goto _out; tr1: #line 383 "rlscan.rl" { word = tokdata; word_len = toklen; } goto st2; st2: if ( ++p == pe ) goto _test_eof2; case 2: #line 615 "rlscan.cpp" if ( (*p) == 59 ) goto tr2; goto tr0; st3: if ( ++p == pe ) goto _test_eof3; case 3: switch( (*p) ) { case 128: goto tr4; case 129: goto tr5; } goto tr3; tr4: #line 382 "rlscan.rl" { word = lit = 0; word_len = lit_len = 0; } #line 383 "rlscan.rl" { word = tokdata; word_len = toklen; } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: #line 638 "rlscan.cpp" switch( (*p) ) { case 59: goto tr6; case 129: goto tr7; } goto tr3; tr5: #line 382 "rlscan.rl" { word = lit = 0; word_len = lit_len = 0; } #line 384 "rlscan.rl" { lit = tokdata; lit_len = toklen; } goto st5; tr7: #line 384 "rlscan.rl" { lit = tokdata; lit_len = toklen; } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: #line 658 "rlscan.cpp" if ( (*p) == 59 ) goto tr6; goto tr3; st6: if ( ++p == pe ) goto _test_eof6; case 6: if ( (*p) == 129 ) goto tr9; goto tr8; tr9: #line 384 "rlscan.rl" { lit = tokdata; lit_len = toklen; } goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: #line 677 "rlscan.cpp" if ( (*p) == 59 ) goto tr10; goto tr8; tr18: #line 413 "rlscan.rl" { if ( active() && machineSpec == 0 && machineName == 0 ) { InputItem *inputItem = new InputItem; inputItem->type = InputItem::Write; inputItem->loc.fileName = fileName; inputItem->loc.line = line; inputItem->loc.col = column; inputItem->name = parser->sectionName; inputItem->pd = parser->pd; id.inputItems.append( inputItem ); } } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: #line 700 "rlscan.cpp" if ( (*p) == 128 ) goto tr12; goto tr11; tr12: #line 427 "rlscan.rl" { if ( active() && machineSpec == 0 && machineName == 0 ) id.inputItems.tail->writeArgs.append( strdup(tokdata) ); } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: #line 715 "rlscan.cpp" switch( (*p) ) { case 59: goto tr13; case 128: goto tr12; } goto tr11; } _test_eof10: cs = 10; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 1: case 2: #line 386 "rlscan.rl" { scan_error() << "bad machine statement" << endl; } break; case 3: case 4: case 5: #line 387 "rlscan.rl" { scan_error() << "bad include statement" << endl; } break; case 6: case 7: #line 388 "rlscan.rl" { scan_error() << "bad import statement" << endl; } break; case 8: case 9: #line 389 "rlscan.rl" { scan_error() << "bad write statement" << endl; } break; #line 758 "rlscan.cpp" } } _out: {} } #line 502 "rlscan.rl" updateCol(); /* Record the last token for use in controlling the scan of subsequent * tokens. */ lastToken = type; } void Scanner::startSection( ) { parserExistsError = false; sectionLoc.fileName = fileName; sectionLoc.line = line; sectionLoc.col = column; } void Scanner::endSection( ) { /* Execute the eof actions for the section parser. */ processToken( -1, 0, 0 ); /* Close off the section with the parser. */ if ( active() ) { InputLoc loc; loc.fileName = fileName; loc.line = line; loc.col = column; parser->token( loc, TK_EndSection, 0, 0 ); } if ( includeDepth == 0 ) { if ( machineSpec == 0 && machineName == 0 ) { /* The end section may include a newline on the end, so * we use the last line, which will count the newline. */ InputItem *inputItem = new InputItem; inputItem->type = InputItem::HostData; inputItem->loc.line = line; inputItem->loc.col = column; id.inputItems.append( inputItem ); } } } bool isAbsolutePath( const char *path ) { #ifdef _WIN32 return isalpha( path[0] ) && path[1] == ':' && path[2] == '\\'; #else return path[0] == '/'; #endif } char **Scanner::makeIncludePathChecks( const char *thisFileName, const char *fileName, int fnlen ) { char **checks = 0; long nextCheck = 0; long length = 0; bool caseInsensitive = false; char *data = prepareLitString( InputLoc(), fileName, fnlen, length, caseInsensitive ); /* Absolute path? */ if ( isAbsolutePath( data ) ) { checks = new char*[2]; checks[nextCheck++] = data; } else { checks = new char*[2 + id.includePaths.length()]; /* Search from the the location of the current file. */ const char *lastSlash = strrchr( thisFileName, PATH_SEP ); if ( lastSlash == 0 ) checks[nextCheck++] = data; else { long givenPathLen = (lastSlash - thisFileName) + 1; long checklen = givenPathLen + length; char *check = new char[checklen+1]; memcpy( check, thisFileName, givenPathLen ); memcpy( check+givenPathLen, data, length ); check[checklen] = 0; checks[nextCheck++] = check; } /* Search from the include paths given on the command line. */ for ( ArgsVector::Iter incp = id.includePaths; incp.lte(); incp++ ) { long pathLen = strlen( *incp ); long checkLen = pathLen + 1 + length; char *check = new char[checkLen+1]; memcpy( check, *incp, pathLen ); check[pathLen] = PATH_SEP; memcpy( check+pathLen+1, data, length ); check[checkLen] = 0; checks[nextCheck++] = check; } } checks[nextCheck] = 0; return checks; } ifstream *Scanner::tryOpenInclude( char **pathChecks, long &found ) { char **check = pathChecks; ifstream *inFile = new ifstream; while ( *check != 0 ) { inFile->open( *check ); if ( inFile->is_open() ) { found = check - pathChecks; return inFile; } /* * 03/26/2011 jg: * Don't rely on sloppy runtime behaviour: reset the state of the stream explicitly. * If inFile->open() fails, which happens when include dirs are tested, the fail bit * is set by the runtime library. Currently the VS runtime library opens new files, * but when it comes to reading it refuses to work. */ inFile->clear(); check += 1; } found = -1; delete inFile; return 0; } #line 1173 "rlscan.rl" #line 904 "rlscan.cpp" static const int rlscan_start = 38; static const int rlscan_first_final = 38; static const int rlscan_error = 0; static const int rlscan_en_inline_code_ruby = 52; static const int rlscan_en_inline_code = 95; static const int rlscan_en_or_literal = 137; static const int rlscan_en_ragel_re_literal = 139; static const int rlscan_en_write_statement = 143; static const int rlscan_en_parser_def = 146; static const int rlscan_en_main_ruby = 253; static const int rlscan_en_main = 38; #line 1176 "rlscan.rl" void Scanner::do_scan() { int bufsize = 8; char *buf = new char[bufsize]; int cs, act, have = 0; int top; /* The stack is two deep, one level for going into ragel defs from the main * machines which process outside code, and another for going into or literals * from either a ragel spec, or a regular expression. */ int stack[2]; int curly_count = 0; bool execute = true; bool singleLineSpec = false; InlineBlockType inlineBlockType = CurlyDelimited; /* Init the section parser and the character scanner. */ init(); #line 940 "rlscan.cpp" { cs = rlscan_start; top = 0; ts = 0; te = 0; act = 0; } #line 1196 "rlscan.rl" /* Set up the start state. FIXME: After 5.20 is released the nocs write * init option should be used, the main machine eliminated and this statement moved * above the write init. */ if ( hostLang->lang == HostLang::Ruby ) cs = rlscan_en_main_ruby; else cs = rlscan_en_main; while ( execute ) { char *p = buf + have; int space = bufsize - have; if ( space == 0 ) { /* We filled up the buffer trying to scan a token. Grow it. */ bufsize = bufsize * 2; char *newbuf = new char[bufsize]; /* Recompute p and space. */ p = newbuf + have; space = bufsize - have; /* Patch up pointers possibly in use. */ if ( ts != 0 ) ts = newbuf + ( ts - buf ); te = newbuf + ( te - buf ); /* Copy the new buffer in. */ memcpy( newbuf, buf, have ); delete[] buf; buf = newbuf; } input.read( p, space ); int len = input.gcount(); char *pe = p + len; /* If we see eof then append the eof var. */ char *eof = 0; if ( len == 0 ) { eof = pe; execute = false; } #line 995 "rlscan.cpp" { if ( p == pe ) goto _test_eof; goto _resume; _again: switch ( cs ) { case 38: goto st38; case 39: goto st39; case 40: goto st40; case 1: goto st1; case 2: goto st2; case 41: goto st41; case 42: goto st42; case 43: goto st43; case 3: goto st3; case 4: goto st4; case 44: goto st44; case 5: goto st5; case 6: goto st6; case 7: goto st7; case 45: goto st45; case 46: goto st46; case 47: goto st47; case 48: goto st48; case 49: goto st49; case 50: goto st50; case 51: goto st51; case 52: goto st52; case 53: goto st53; case 54: goto st54; case 8: goto st8; case 9: goto st9; case 55: goto st55; case 10: goto st10; case 56: goto st56; case 11: goto st11; case 12: goto st12; case 57: goto st57; case 13: goto st13; case 14: goto st14; case 58: goto st58; case 59: goto st59; case 15: goto st15; case 60: goto st60; case 61: goto st61; case 62: goto st62; case 63: goto st63; case 64: goto st64; case 65: goto st65; case 66: goto st66; case 67: goto st67; case 68: goto st68; case 69: goto st69; case 70: goto st70; case 71: goto st71; case 72: goto st72; case 73: goto st73; case 74: goto st74; case 75: goto st75; case 76: goto st76; case 77: goto st77; case 78: goto st78; case 79: goto st79; case 80: goto st80; case 81: goto st81; case 82: goto st82; case 83: goto st83; case 84: goto st84; case 85: goto st85; case 86: goto st86; case 87: goto st87; case 88: goto st88; case 89: goto st89; case 90: goto st90; case 91: goto st91; case 92: goto st92; case 93: goto st93; case 94: goto st94; case 95: goto st95; case 96: goto st96; case 97: goto st97; case 16: goto st16; case 17: goto st17; case 98: goto st98; case 18: goto st18; case 19: goto st19; case 99: goto st99; case 20: goto st20; case 21: goto st21; case 22: goto st22; case 100: goto st100; case 101: goto st101; case 23: goto st23; case 102: goto st102; case 103: goto st103; case 104: goto st104; case 105: goto st105; case 106: goto st106; case 107: goto st107; case 108: goto st108; case 109: goto st109; case 110: goto st110; case 111: goto st111; case 112: goto st112; case 113: goto st113; case 114: goto st114; case 115: goto st115; case 116: goto st116; case 117: goto st117; case 118: goto st118; case 119: goto st119; case 120: goto st120; case 121: goto st121; case 122: goto st122; case 123: goto st123; case 124: goto st124; case 125: goto st125; case 126: goto st126; case 127: goto st127; case 128: goto st128; case 129: goto st129; case 130: goto st130; case 131: goto st131; case 132: goto st132; case 133: goto st133; case 134: goto st134; case 135: goto st135; case 136: goto st136; case 137: goto st137; case 138: goto st138; case 139: goto st139; case 140: goto st140; case 141: goto st141; case 142: goto st142; case 143: goto st143; case 0: goto st0; case 144: goto st144; case 145: goto st145; case 146: goto st146; case 147: goto st147; case 148: goto st148; case 24: goto st24; case 149: goto st149; case 25: goto st25; case 150: goto st150; case 26: goto st26; case 151: goto st151; case 152: goto st152; case 153: goto st153; case 27: goto st27; case 28: goto st28; case 154: goto st154; case 155: goto st155; case 156: goto st156; case 157: goto st157; case 158: goto st158; case 29: goto st29; case 159: goto st159; case 160: goto st160; case 161: goto st161; case 162: goto st162; case 163: goto st163; case 164: goto st164; case 165: goto st165; case 166: goto st166; case 167: goto st167; case 168: goto st168; case 169: goto st169; case 170: goto st170; case 171: goto st171; case 172: goto st172; case 173: goto st173; case 174: goto st174; case 175: goto st175; case 176: goto st176; case 177: goto st177; case 178: goto st178; case 179: goto st179; case 180: goto st180; case 181: goto st181; case 182: goto st182; case 183: goto st183; case 184: goto st184; case 185: goto st185; case 186: goto st186; case 187: goto st187; case 188: goto st188; case 189: goto st189; case 190: goto st190; case 191: goto st191; case 192: goto st192; case 193: goto st193; case 194: goto st194; case 195: goto st195; case 196: goto st196; case 197: goto st197; case 198: goto st198; case 199: goto st199; case 200: goto st200; case 201: goto st201; case 202: goto st202; case 203: goto st203; case 204: goto st204; case 205: goto st205; case 206: goto st206; case 207: goto st207; case 208: goto st208; case 209: goto st209; case 210: goto st210; case 211: goto st211; case 212: goto st212; case 213: goto st213; case 214: goto st214; case 215: goto st215; case 216: goto st216; case 217: goto st217; case 218: goto st218; case 219: goto st219; case 220: goto st220; case 221: goto st221; case 222: goto st222; case 223: goto st223; case 224: goto st224; case 225: goto st225; case 226: goto st226; case 227: goto st227; case 228: goto st228; case 229: goto st229; case 230: goto st230; case 231: goto st231; case 232: goto st232; case 233: goto st233; case 234: goto st234; case 235: goto st235; case 236: goto st236; case 237: goto st237; case 238: goto st238; case 239: goto st239; case 240: goto st240; case 241: goto st241; case 242: goto st242; case 243: goto st243; case 244: goto st244; case 245: goto st245; case 246: goto st246; case 247: goto st247; case 248: goto st248; case 249: goto st249; case 250: goto st250; case 251: goto st251; case 252: goto st252; case 30: goto st30; case 253: goto st253; case 254: goto st254; case 255: goto st255; case 31: goto st31; case 32: goto st32; case 256: goto st256; case 33: goto st33; case 257: goto st257; case 258: goto st258; case 259: goto st259; case 34: goto st34; case 35: goto st35; case 260: goto st260; case 36: goto st36; case 37: goto st37; case 261: goto st261; case 262: goto st262; default: break; } if ( ++p == pe ) goto _test_eof; _resume: switch ( cs ) { tr0: #line 1171 "rlscan.rl" {{p = ((te))-1;}{ pass( *ts, 0, 0 ); }} goto st38; tr3: #line 1155 "rlscan.rl" {te = p+1;{ pass( IMP_Literal, ts, te ); }} goto st38; tr11: #line 1154 "rlscan.rl" {te = p+1;{ pass(); }} goto st38; tr13: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } #line 1154 "rlscan.rl" {te = p+1;{ pass(); }} goto st38; tr71: #line 1171 "rlscan.rl" {te = p+1;{ pass( *ts, 0, 0 ); }} goto st38; tr72: #line 1170 "rlscan.rl" {te = p+1;} goto st38; tr82: #line 1169 "rlscan.rl" {te = p;p--;{ pass(); }} goto st38; tr83: #line 1171 "rlscan.rl" {te = p;p--;{ pass( *ts, 0, 0 ); }} goto st38; tr85: #line 1163 "rlscan.rl" {te = p;p--;{ updateCol(); singleLineSpec = true; startSection(); {stack[top++] = 38; goto st146;} }} goto st38; tr86: #line 1157 "rlscan.rl" {te = p+1;{ updateCol(); singleLineSpec = false; startSection(); {stack[top++] = 38; goto st146;} }} goto st38; tr87: #line 1153 "rlscan.rl" {te = p;p--;{ pass( IMP_UInt, ts, te ); }} goto st38; tr88: #line 1 "NONE" { switch( act ) { case 176: {{p = ((te))-1;} pass( IMP_Define, 0, 0 ); } break; case 177: {{p = ((te))-1;} pass( IMP_Word, ts, te ); } break; } } goto st38; tr89: #line 1152 "rlscan.rl" {te = p;p--;{ pass( IMP_Word, ts, te ); }} goto st38; st38: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof38; case 38: #line 1 "NONE" {ts = p;} #line 1358 "rlscan.cpp" switch( (*p) ) { case 0: goto tr72; case 9: goto st39; case 10: goto tr74; case 32: goto st39; case 34: goto tr75; case 37: goto st41; case 39: goto tr77; case 47: goto tr78; case 95: goto tr80; case 100: goto st47; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st45; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr71; tr74: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st39; st39: if ( ++p == pe ) goto _test_eof39; case 39: #line 1392 "rlscan.cpp" switch( (*p) ) { case 9: goto st39; case 10: goto tr74; case 32: goto st39; } goto tr82; tr75: #line 1 "NONE" {te = p+1;} goto st40; st40: if ( ++p == pe ) goto _test_eof40; case 40: #line 1407 "rlscan.cpp" switch( (*p) ) { case 10: goto tr2; case 34: goto tr3; case 92: goto st2; } goto st1; tr2: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st1; st1: if ( ++p == pe ) goto _test_eof1; case 1: #line 1426 "rlscan.cpp" switch( (*p) ) { case 10: goto tr2; case 34: goto tr3; case 92: goto st2; } goto st1; st2: if ( ++p == pe ) goto _test_eof2; case 2: if ( (*p) == 10 ) goto tr2; goto st1; st41: if ( ++p == pe ) goto _test_eof41; case 41: if ( (*p) == 37 ) goto st42; goto tr83; st42: if ( ++p == pe ) goto _test_eof42; case 42: if ( (*p) == 123 ) goto tr86; goto tr85; tr77: #line 1 "NONE" {te = p+1;} goto st43; st43: if ( ++p == pe ) goto _test_eof43; case 43: #line 1462 "rlscan.cpp" switch( (*p) ) { case 10: goto tr6; case 39: goto tr3; case 92: goto st4; } goto st3; tr6: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st3; st3: if ( ++p == pe ) goto _test_eof3; case 3: #line 1481 "rlscan.cpp" switch( (*p) ) { case 10: goto tr6; case 39: goto tr3; case 92: goto st4; } goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: if ( (*p) == 10 ) goto tr6; goto st3; tr78: #line 1 "NONE" {te = p+1;} goto st44; st44: if ( ++p == pe ) goto _test_eof44; case 44: #line 1503 "rlscan.cpp" switch( (*p) ) { case 42: goto st5; case 47: goto st7; } goto tr83; tr9: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: #line 1521 "rlscan.cpp" switch( (*p) ) { case 10: goto tr9; case 42: goto st6; } goto st5; st6: if ( ++p == pe ) goto _test_eof6; case 6: switch( (*p) ) { case 10: goto tr9; case 42: goto st6; case 47: goto tr11; } goto st5; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( (*p) == 10 ) goto tr13; goto st7; st45: if ( ++p == pe ) goto _test_eof45; case 45: if ( 48 <= (*p) && (*p) <= 57 ) goto st45; goto tr87; tr80: #line 1 "NONE" {te = p+1;} #line 1152 "rlscan.rl" {act = 177;} goto st46; tr94: #line 1 "NONE" {te = p+1;} #line 1151 "rlscan.rl" {act = 176;} goto st46; st46: if ( ++p == pe ) goto _test_eof46; case 46: #line 1567 "rlscan.cpp" if ( (*p) == 95 ) goto tr80; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr80; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr88; st47: if ( ++p == pe ) goto _test_eof47; case 47: switch( (*p) ) { case 95: goto tr80; case 101: goto st48; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr80; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr89; st48: if ( ++p == pe ) goto _test_eof48; case 48: switch( (*p) ) { case 95: goto tr80; case 102: goto st49; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr80; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr89; st49: if ( ++p == pe ) goto _test_eof49; case 49: switch( (*p) ) { case 95: goto tr80; case 105: goto st50; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr80; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr89; st50: if ( ++p == pe ) goto _test_eof50; case 50: switch( (*p) ) { case 95: goto tr80; case 110: goto st51; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr80; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr89; st51: if ( ++p == pe ) goto _test_eof51; case 51: switch( (*p) ) { case 95: goto tr80; case 101: goto tr94; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr80; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr80; } else goto tr80; goto tr89; tr14: #line 770 "rlscan.rl" {{p = ((te))-1;}{ token( IL_Symbol, ts, te ); }} goto st52; tr17: #line 716 "rlscan.rl" {te = p+1;{ token( IL_Literal, ts, te ); }} goto st52; tr20: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } #line 723 "rlscan.rl" {te = p+1;{ token( IL_Comment, ts, te ); }} goto st52; tr27: #line 712 "rlscan.rl" {{p = ((te))-1;}{ token( TK_UInt, ts, te ); }} goto st52; tr95: #line 770 "rlscan.rl" {te = p+1;{ token( IL_Symbol, ts, te ); }} goto st52; tr96: #line 765 "rlscan.rl" {te = p+1;{ scan_error() << "unterminated code block" << endl; }} goto st52; tr102: #line 745 "rlscan.rl" {te = p+1;{ token( *ts, ts, te ); }} goto st52; tr103: #line 740 "rlscan.rl" {te = p+1;{ whitespaceOn = true; token( *ts, ts, te ); }} goto st52; tr108: #line 733 "rlscan.rl" {te = p+1;{ whitespaceOn = true; token( *ts, ts, te ); if ( inlineBlockType == SemiTerminated ) {cs = stack[--top];goto _again;} }} goto st52; tr111: #line 747 "rlscan.rl" {te = p+1;{ token( IL_Symbol, ts, te ); curly_count += 1; }} goto st52; tr112: #line 752 "rlscan.rl" {te = p+1;{ if ( --curly_count == 0 && inlineBlockType == CurlyDelimited ) { /* Inline code block ends. */ token( '}' ); {cs = stack[--top];goto _again;} } else { /* Either a semi terminated inline block or only the closing * brace of some inner scope, not the block's closing brace. */ token( IL_Symbol, ts, te ); } }} goto st52; tr113: #line 718 "rlscan.rl" {te = p;p--;{ if ( whitespaceOn ) token( IL_WhiteSpace, ts, te ); }} goto st52; tr114: #line 770 "rlscan.rl" {te = p;p--;{ token( IL_Symbol, ts, te ); }} goto st52; tr115: #line 712 "rlscan.rl" {te = p;p--;{ token( TK_UInt, ts, te ); }} goto st52; tr117: #line 713 "rlscan.rl" {te = p;p--;{ token( TK_Hex, ts, te ); }} goto st52; tr118: #line 725 "rlscan.rl" {te = p+1;{ token( TK_NameSep, ts, te ); }} goto st52; tr119: #line 1 "NONE" { switch( act ) { case 1: {{p = ((te))-1;} token( KW_PChar ); } break; case 3: {{p = ((te))-1;} token( KW_CurState ); } break; case 4: {{p = ((te))-1;} token( KW_TargState ); } break; case 5: {{p = ((te))-1;} whitespaceOn = false; token( KW_Entry ); } break; case 6: {{p = ((te))-1;} whitespaceOn = false; token( KW_Hold ); } break; case 7: {{p = ((te))-1;} token( KW_Exec, 0, 0 ); } break; case 8: {{p = ((te))-1;} whitespaceOn = false; token( KW_Goto ); } break; case 9: {{p = ((te))-1;} whitespaceOn = false; token( KW_Next ); } break; case 10: {{p = ((te))-1;} whitespaceOn = false; token( KW_Call ); } break; case 11: {{p = ((te))-1;} whitespaceOn = false; token( KW_Ret ); } break; case 12: {{p = ((te))-1;} whitespaceOn = false; token( KW_Break ); } break; case 13: {{p = ((te))-1;} token( TK_Word, ts, te ); } break; } } goto st52; tr120: #line 710 "rlscan.rl" {te = p;p--;{ token( TK_Word, ts, te ); }} goto st52; tr134: #line 675 "rlscan.rl" {te = p;p--;{ token( KW_Char ); }} goto st52; st52: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof52; case 52: #line 1 "NONE" {ts = p;} #line 1840 "rlscan.cpp" switch( (*p) ) { case 0: goto tr96; case 9: goto st53; case 10: goto tr98; case 32: goto st53; case 34: goto tr99; case 35: goto tr100; case 39: goto tr101; case 40: goto tr102; case 44: goto tr102; case 47: goto tr104; case 48: goto tr105; case 58: goto st61; case 59: goto tr108; case 95: goto tr109; case 102: goto st63; case 123: goto tr111; case 125: goto tr112; } if ( (*p) < 49 ) { if ( 41 <= (*p) && (*p) <= 42 ) goto tr103; } else if ( (*p) > 57 ) { if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else if ( (*p) >= 65 ) goto tr109; } else goto st59; goto tr95; tr98: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st53; st53: if ( ++p == pe ) goto _test_eof53; case 53: #line 1884 "rlscan.cpp" switch( (*p) ) { case 9: goto st53; case 10: goto tr98; case 32: goto st53; } goto tr113; tr99: #line 1 "NONE" {te = p+1;} goto st54; st54: if ( ++p == pe ) goto _test_eof54; case 54: #line 1899 "rlscan.cpp" switch( (*p) ) { case 10: goto tr16; case 34: goto tr17; case 92: goto st9; } goto st8; tr16: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: #line 1918 "rlscan.cpp" switch( (*p) ) { case 10: goto tr16; case 34: goto tr17; case 92: goto st9; } goto st8; st9: if ( ++p == pe ) goto _test_eof9; case 9: if ( (*p) == 10 ) goto tr16; goto st8; tr100: #line 1 "NONE" {te = p+1;} goto st55; st55: if ( ++p == pe ) goto _test_eof55; case 55: #line 1940 "rlscan.cpp" if ( (*p) == 10 ) goto tr20; goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: if ( (*p) == 10 ) goto tr20; goto st10; tr101: #line 1 "NONE" {te = p+1;} goto st56; st56: if ( ++p == pe ) goto _test_eof56; case 56: #line 1959 "rlscan.cpp" switch( (*p) ) { case 10: goto tr22; case 39: goto tr17; case 92: goto st12; } goto st11; tr22: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st11; st11: if ( ++p == pe ) goto _test_eof11; case 11: #line 1978 "rlscan.cpp" switch( (*p) ) { case 10: goto tr22; case 39: goto tr17; case 92: goto st12; } goto st11; st12: if ( ++p == pe ) goto _test_eof12; case 12: if ( (*p) == 10 ) goto tr22; goto st11; tr104: #line 1 "NONE" {te = p+1;} goto st57; st57: if ( ++p == pe ) goto _test_eof57; case 57: #line 2000 "rlscan.cpp" switch( (*p) ) { case 10: goto tr25; case 47: goto tr17; case 92: goto st14; } goto st13; tr25: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st13; st13: if ( ++p == pe ) goto _test_eof13; case 13: #line 2019 "rlscan.cpp" switch( (*p) ) { case 10: goto tr25; case 47: goto tr17; case 92: goto st14; } goto st13; st14: if ( ++p == pe ) goto _test_eof14; case 14: if ( (*p) == 10 ) goto tr25; goto st13; tr105: #line 1 "NONE" {te = p+1;} goto st58; st58: if ( ++p == pe ) goto _test_eof58; case 58: #line 2041 "rlscan.cpp" if ( (*p) == 120 ) goto st15; if ( 48 <= (*p) && (*p) <= 57 ) goto st59; goto tr115; st59: if ( ++p == pe ) goto _test_eof59; case 59: if ( 48 <= (*p) && (*p) <= 57 ) goto st59; goto tr115; st15: if ( ++p == pe ) goto _test_eof15; case 15: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st60; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st60; } else goto st60; goto tr27; st60: if ( ++p == pe ) goto _test_eof60; case 60: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st60; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st60; } else goto st60; goto tr117; st61: if ( ++p == pe ) goto _test_eof61; case 61: if ( (*p) == 58 ) goto tr118; goto tr114; tr109: #line 1 "NONE" {te = p+1;} #line 710 "rlscan.rl" {act = 13;} goto st62; tr133: #line 1 "NONE" {te = p+1;} #line 705 "rlscan.rl" {act = 12;} goto st62; tr138: #line 1 "NONE" {te = p+1;} #line 697 "rlscan.rl" {act = 10;} goto st62; tr140: #line 1 "NONE" {te = p+1;} #line 676 "rlscan.rl" {act = 3;} goto st62; tr145: #line 1 "NONE" {te = p+1;} #line 678 "rlscan.rl" {act = 5;} goto st62; tr147: #line 1 "NONE" {te = p+1;} #line 688 "rlscan.rl" {act = 7;} goto st62; tr150: #line 1 "NONE" {te = p+1;} #line 689 "rlscan.rl" {act = 8;} goto st62; tr153: #line 1 "NONE" {te = p+1;} #line 684 "rlscan.rl" {act = 6;} goto st62; tr156: #line 1 "NONE" {te = p+1;} #line 693 "rlscan.rl" {act = 9;} goto st62; tr157: #line 1 "NONE" {te = p+1;} #line 674 "rlscan.rl" {act = 1;} goto st62; tr159: #line 1 "NONE" {te = p+1;} #line 701 "rlscan.rl" {act = 11;} goto st62; tr163: #line 1 "NONE" {te = p+1;} #line 677 "rlscan.rl" {act = 4;} goto st62; st62: if ( ++p == pe ) goto _test_eof62; case 62: #line 2163 "rlscan.cpp" if ( (*p) == 95 ) goto tr109; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr119; st63: if ( ++p == pe ) goto _test_eof63; case 63: switch( (*p) ) { case 95: goto tr109; case 98: goto st64; case 99: goto st68; case 101: goto st73; case 103: goto st79; case 104: goto st82; case 110: goto st85; case 112: goto st88; case 114: goto st89; case 116: goto st91; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st64: if ( ++p == pe ) goto _test_eof64; case 64: switch( (*p) ) { case 95: goto tr109; case 114: goto st65; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st65: if ( ++p == pe ) goto _test_eof65; case 65: switch( (*p) ) { case 95: goto tr109; case 101: goto st66; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st66: if ( ++p == pe ) goto _test_eof66; case 66: switch( (*p) ) { case 95: goto tr109; case 97: goto st67; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st67: if ( ++p == pe ) goto _test_eof67; case 67: switch( (*p) ) { case 95: goto tr109; case 107: goto tr133; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st68: if ( ++p == pe ) goto _test_eof68; case 68: switch( (*p) ) { case 95: goto tr109; case 97: goto st69; case 117: goto st71; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr134; st69: if ( ++p == pe ) goto _test_eof69; case 69: switch( (*p) ) { case 95: goto tr109; case 108: goto st70; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st70: if ( ++p == pe ) goto _test_eof70; case 70: switch( (*p) ) { case 95: goto tr109; case 108: goto tr138; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st71: if ( ++p == pe ) goto _test_eof71; case 71: switch( (*p) ) { case 95: goto tr109; case 114: goto st72; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st72: if ( ++p == pe ) goto _test_eof72; case 72: switch( (*p) ) { case 95: goto tr109; case 115: goto tr140; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st73: if ( ++p == pe ) goto _test_eof73; case 73: switch( (*p) ) { case 95: goto tr109; case 110: goto st74; case 120: goto st77; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st74: if ( ++p == pe ) goto _test_eof74; case 74: switch( (*p) ) { case 95: goto tr109; case 116: goto st75; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st75: if ( ++p == pe ) goto _test_eof75; case 75: switch( (*p) ) { case 95: goto tr109; case 114: goto st76; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st76: if ( ++p == pe ) goto _test_eof76; case 76: switch( (*p) ) { case 95: goto tr109; case 121: goto tr145; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st77: if ( ++p == pe ) goto _test_eof77; case 77: switch( (*p) ) { case 95: goto tr109; case 101: goto st78; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st78: if ( ++p == pe ) goto _test_eof78; case 78: switch( (*p) ) { case 95: goto tr109; case 99: goto tr147; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st79: if ( ++p == pe ) goto _test_eof79; case 79: switch( (*p) ) { case 95: goto tr109; case 111: goto st80; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st80: if ( ++p == pe ) goto _test_eof80; case 80: switch( (*p) ) { case 95: goto tr109; case 116: goto st81; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st81: if ( ++p == pe ) goto _test_eof81; case 81: switch( (*p) ) { case 95: goto tr109; case 111: goto tr150; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st82: if ( ++p == pe ) goto _test_eof82; case 82: switch( (*p) ) { case 95: goto tr109; case 111: goto st83; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st83: if ( ++p == pe ) goto _test_eof83; case 83: switch( (*p) ) { case 95: goto tr109; case 108: goto st84; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st84: if ( ++p == pe ) goto _test_eof84; case 84: switch( (*p) ) { case 95: goto tr109; case 100: goto tr153; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st85: if ( ++p == pe ) goto _test_eof85; case 85: switch( (*p) ) { case 95: goto tr109; case 101: goto st86; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st86: if ( ++p == pe ) goto _test_eof86; case 86: switch( (*p) ) { case 95: goto tr109; case 120: goto st87; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st87: if ( ++p == pe ) goto _test_eof87; case 87: switch( (*p) ) { case 95: goto tr109; case 116: goto tr156; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st88: if ( ++p == pe ) goto _test_eof88; case 88: switch( (*p) ) { case 95: goto tr109; case 99: goto tr157; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st89: if ( ++p == pe ) goto _test_eof89; case 89: switch( (*p) ) { case 95: goto tr109; case 101: goto st90; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st90: if ( ++p == pe ) goto _test_eof90; case 90: switch( (*p) ) { case 95: goto tr109; case 116: goto tr159; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st91: if ( ++p == pe ) goto _test_eof91; case 91: switch( (*p) ) { case 95: goto tr109; case 97: goto st92; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st92: if ( ++p == pe ) goto _test_eof92; case 92: switch( (*p) ) { case 95: goto tr109; case 114: goto st93; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st93: if ( ++p == pe ) goto _test_eof93; case 93: switch( (*p) ) { case 95: goto tr109; case 103: goto st94; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; st94: if ( ++p == pe ) goto _test_eof94; case 94: switch( (*p) ) { case 95: goto tr109; case 115: goto tr163; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr109; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr109; } else goto tr109; goto tr120; tr29: #line 873 "rlscan.rl" {{p = ((te))-1;}{ token( IL_Symbol, ts, te ); }} goto st95; tr32: #line 819 "rlscan.rl" {te = p+1;{ token( IL_Literal, ts, te ); }} goto st95; tr40: #line 826 "rlscan.rl" {te = p+1;{ token( IL_Comment, ts, te ); }} goto st95; tr42: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } #line 826 "rlscan.rl" {te = p+1;{ token( IL_Comment, ts, te ); }} goto st95; tr43: #line 815 "rlscan.rl" {{p = ((te))-1;}{ token( TK_UInt, ts, te ); }} goto st95; tr164: #line 873 "rlscan.rl" {te = p+1;{ token( IL_Symbol, ts, te ); }} goto st95; tr165: #line 868 "rlscan.rl" {te = p+1;{ scan_error() << "unterminated code block" << endl; }} goto st95; tr170: #line 848 "rlscan.rl" {te = p+1;{ token( *ts, ts, te ); }} goto st95; tr171: #line 843 "rlscan.rl" {te = p+1;{ whitespaceOn = true; token( *ts, ts, te ); }} goto st95; tr176: #line 836 "rlscan.rl" {te = p+1;{ whitespaceOn = true; token( *ts, ts, te ); if ( inlineBlockType == SemiTerminated ) {cs = stack[--top];goto _again;} }} goto st95; tr179: #line 850 "rlscan.rl" {te = p+1;{ token( IL_Symbol, ts, te ); curly_count += 1; }} goto st95; tr180: #line 855 "rlscan.rl" {te = p+1;{ if ( --curly_count == 0 && inlineBlockType == CurlyDelimited ) { /* Inline code block ends. */ token( '}' ); {cs = stack[--top];goto _again;} } else { /* Either a semi terminated inline block or only the closing * brace of some inner scope, not the block's closing brace. */ token( IL_Symbol, ts, te ); } }} goto st95; tr181: #line 821 "rlscan.rl" {te = p;p--;{ if ( whitespaceOn ) token( IL_WhiteSpace, ts, te ); }} goto st95; tr182: #line 873 "rlscan.rl" {te = p;p--;{ token( IL_Symbol, ts, te ); }} goto st95; tr183: #line 815 "rlscan.rl" {te = p;p--;{ token( TK_UInt, ts, te ); }} goto st95; tr185: #line 816 "rlscan.rl" {te = p;p--;{ token( TK_Hex, ts, te ); }} goto st95; tr186: #line 828 "rlscan.rl" {te = p+1;{ token( TK_NameSep, ts, te ); }} goto st95; tr187: #line 1 "NONE" { switch( act ) { case 27: {{p = ((te))-1;} token( KW_PChar ); } break; case 29: {{p = ((te))-1;} token( KW_CurState ); } break; case 30: {{p = ((te))-1;} token( KW_TargState ); } break; case 31: {{p = ((te))-1;} whitespaceOn = false; token( KW_Entry ); } break; case 32: {{p = ((te))-1;} whitespaceOn = false; token( KW_Hold ); } break; case 33: {{p = ((te))-1;} token( KW_Exec, 0, 0 ); } break; case 34: {{p = ((te))-1;} whitespaceOn = false; token( KW_Goto ); } break; case 35: {{p = ((te))-1;} whitespaceOn = false; token( KW_Next ); } break; case 36: {{p = ((te))-1;} whitespaceOn = false; token( KW_Call ); } break; case 37: {{p = ((te))-1;} whitespaceOn = false; token( KW_Ret ); } break; case 38: {{p = ((te))-1;} whitespaceOn = false; token( KW_Break ); } break; case 39: {{p = ((te))-1;} token( TK_Word, ts, te ); } break; } } goto st95; tr188: #line 813 "rlscan.rl" {te = p;p--;{ token( TK_Word, ts, te ); }} goto st95; tr202: #line 778 "rlscan.rl" {te = p;p--;{ token( KW_Char ); }} goto st95; st95: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof95; case 95: #line 1 "NONE" {ts = p;} #line 2909 "rlscan.cpp" switch( (*p) ) { case 0: goto tr165; case 9: goto st96; case 10: goto tr167; case 32: goto st96; case 34: goto tr168; case 39: goto tr169; case 40: goto tr170; case 44: goto tr170; case 47: goto tr172; case 48: goto tr173; case 58: goto st103; case 59: goto tr176; case 95: goto tr177; case 102: goto st105; case 123: goto tr179; case 125: goto tr180; } if ( (*p) < 49 ) { if ( 41 <= (*p) && (*p) <= 42 ) goto tr171; } else if ( (*p) > 57 ) { if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else if ( (*p) >= 65 ) goto tr177; } else goto st101; goto tr164; tr167: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st96; st96: if ( ++p == pe ) goto _test_eof96; case 96: #line 2952 "rlscan.cpp" switch( (*p) ) { case 9: goto st96; case 10: goto tr167; case 32: goto st96; } goto tr181; tr168: #line 1 "NONE" {te = p+1;} goto st97; st97: if ( ++p == pe ) goto _test_eof97; case 97: #line 2967 "rlscan.cpp" switch( (*p) ) { case 10: goto tr31; case 34: goto tr32; case 92: goto st17; } goto st16; tr31: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st16; st16: if ( ++p == pe ) goto _test_eof16; case 16: #line 2986 "rlscan.cpp" switch( (*p) ) { case 10: goto tr31; case 34: goto tr32; case 92: goto st17; } goto st16; st17: if ( ++p == pe ) goto _test_eof17; case 17: if ( (*p) == 10 ) goto tr31; goto st16; tr169: #line 1 "NONE" {te = p+1;} goto st98; st98: if ( ++p == pe ) goto _test_eof98; case 98: #line 3008 "rlscan.cpp" switch( (*p) ) { case 10: goto tr35; case 39: goto tr32; case 92: goto st19; } goto st18; tr35: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st18; st18: if ( ++p == pe ) goto _test_eof18; case 18: #line 3027 "rlscan.cpp" switch( (*p) ) { case 10: goto tr35; case 39: goto tr32; case 92: goto st19; } goto st18; st19: if ( ++p == pe ) goto _test_eof19; case 19: if ( (*p) == 10 ) goto tr35; goto st18; tr172: #line 1 "NONE" {te = p+1;} goto st99; st99: if ( ++p == pe ) goto _test_eof99; case 99: #line 3049 "rlscan.cpp" switch( (*p) ) { case 42: goto st20; case 47: goto st22; } goto tr182; tr38: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st20; st20: if ( ++p == pe ) goto _test_eof20; case 20: #line 3067 "rlscan.cpp" switch( (*p) ) { case 10: goto tr38; case 42: goto st21; } goto st20; st21: if ( ++p == pe ) goto _test_eof21; case 21: switch( (*p) ) { case 10: goto tr38; case 42: goto st21; case 47: goto tr40; } goto st20; st22: if ( ++p == pe ) goto _test_eof22; case 22: if ( (*p) == 10 ) goto tr42; goto st22; tr173: #line 1 "NONE" {te = p+1;} goto st100; st100: if ( ++p == pe ) goto _test_eof100; case 100: #line 3098 "rlscan.cpp" if ( (*p) == 120 ) goto st23; if ( 48 <= (*p) && (*p) <= 57 ) goto st101; goto tr183; st101: if ( ++p == pe ) goto _test_eof101; case 101: if ( 48 <= (*p) && (*p) <= 57 ) goto st101; goto tr183; st23: if ( ++p == pe ) goto _test_eof23; case 23: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st102; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st102; } else goto st102; goto tr43; st102: if ( ++p == pe ) goto _test_eof102; case 102: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st102; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st102; } else goto st102; goto tr185; st103: if ( ++p == pe ) goto _test_eof103; case 103: if ( (*p) == 58 ) goto tr186; goto tr182; tr177: #line 1 "NONE" {te = p+1;} #line 813 "rlscan.rl" {act = 39;} goto st104; tr201: #line 1 "NONE" {te = p+1;} #line 808 "rlscan.rl" {act = 38;} goto st104; tr206: #line 1 "NONE" {te = p+1;} #line 800 "rlscan.rl" {act = 36;} goto st104; tr208: #line 1 "NONE" {te = p+1;} #line 779 "rlscan.rl" {act = 29;} goto st104; tr213: #line 1 "NONE" {te = p+1;} #line 781 "rlscan.rl" {act = 31;} goto st104; tr215: #line 1 "NONE" {te = p+1;} #line 791 "rlscan.rl" {act = 33;} goto st104; tr218: #line 1 "NONE" {te = p+1;} #line 792 "rlscan.rl" {act = 34;} goto st104; tr221: #line 1 "NONE" {te = p+1;} #line 787 "rlscan.rl" {act = 32;} goto st104; tr224: #line 1 "NONE" {te = p+1;} #line 796 "rlscan.rl" {act = 35;} goto st104; tr225: #line 1 "NONE" {te = p+1;} #line 777 "rlscan.rl" {act = 27;} goto st104; tr227: #line 1 "NONE" {te = p+1;} #line 804 "rlscan.rl" {act = 37;} goto st104; tr231: #line 1 "NONE" {te = p+1;} #line 780 "rlscan.rl" {act = 30;} goto st104; st104: if ( ++p == pe ) goto _test_eof104; case 104: #line 3220 "rlscan.cpp" if ( (*p) == 95 ) goto tr177; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr187; st105: if ( ++p == pe ) goto _test_eof105; case 105: switch( (*p) ) { case 95: goto tr177; case 98: goto st106; case 99: goto st110; case 101: goto st115; case 103: goto st121; case 104: goto st124; case 110: goto st127; case 112: goto st130; case 114: goto st131; case 116: goto st133; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st106: if ( ++p == pe ) goto _test_eof106; case 106: switch( (*p) ) { case 95: goto tr177; case 114: goto st107; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st107: if ( ++p == pe ) goto _test_eof107; case 107: switch( (*p) ) { case 95: goto tr177; case 101: goto st108; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st108: if ( ++p == pe ) goto _test_eof108; case 108: switch( (*p) ) { case 95: goto tr177; case 97: goto st109; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st109: if ( ++p == pe ) goto _test_eof109; case 109: switch( (*p) ) { case 95: goto tr177; case 107: goto tr201; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st110: if ( ++p == pe ) goto _test_eof110; case 110: switch( (*p) ) { case 95: goto tr177; case 97: goto st111; case 117: goto st113; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr202; st111: if ( ++p == pe ) goto _test_eof111; case 111: switch( (*p) ) { case 95: goto tr177; case 108: goto st112; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st112: if ( ++p == pe ) goto _test_eof112; case 112: switch( (*p) ) { case 95: goto tr177; case 108: goto tr206; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st113: if ( ++p == pe ) goto _test_eof113; case 113: switch( (*p) ) { case 95: goto tr177; case 114: goto st114; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st114: if ( ++p == pe ) goto _test_eof114; case 114: switch( (*p) ) { case 95: goto tr177; case 115: goto tr208; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st115: if ( ++p == pe ) goto _test_eof115; case 115: switch( (*p) ) { case 95: goto tr177; case 110: goto st116; case 120: goto st119; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st116: if ( ++p == pe ) goto _test_eof116; case 116: switch( (*p) ) { case 95: goto tr177; case 116: goto st117; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st117: if ( ++p == pe ) goto _test_eof117; case 117: switch( (*p) ) { case 95: goto tr177; case 114: goto st118; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st118: if ( ++p == pe ) goto _test_eof118; case 118: switch( (*p) ) { case 95: goto tr177; case 121: goto tr213; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st119: if ( ++p == pe ) goto _test_eof119; case 119: switch( (*p) ) { case 95: goto tr177; case 101: goto st120; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st120: if ( ++p == pe ) goto _test_eof120; case 120: switch( (*p) ) { case 95: goto tr177; case 99: goto tr215; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st121: if ( ++p == pe ) goto _test_eof121; case 121: switch( (*p) ) { case 95: goto tr177; case 111: goto st122; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st122: if ( ++p == pe ) goto _test_eof122; case 122: switch( (*p) ) { case 95: goto tr177; case 116: goto st123; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st123: if ( ++p == pe ) goto _test_eof123; case 123: switch( (*p) ) { case 95: goto tr177; case 111: goto tr218; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st124: if ( ++p == pe ) goto _test_eof124; case 124: switch( (*p) ) { case 95: goto tr177; case 111: goto st125; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st125: if ( ++p == pe ) goto _test_eof125; case 125: switch( (*p) ) { case 95: goto tr177; case 108: goto st126; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st126: if ( ++p == pe ) goto _test_eof126; case 126: switch( (*p) ) { case 95: goto tr177; case 100: goto tr221; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st127: if ( ++p == pe ) goto _test_eof127; case 127: switch( (*p) ) { case 95: goto tr177; case 101: goto st128; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st128: if ( ++p == pe ) goto _test_eof128; case 128: switch( (*p) ) { case 95: goto tr177; case 120: goto st129; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st129: if ( ++p == pe ) goto _test_eof129; case 129: switch( (*p) ) { case 95: goto tr177; case 116: goto tr224; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st130: if ( ++p == pe ) goto _test_eof130; case 130: switch( (*p) ) { case 95: goto tr177; case 99: goto tr225; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st131: if ( ++p == pe ) goto _test_eof131; case 131: switch( (*p) ) { case 95: goto tr177; case 101: goto st132; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st132: if ( ++p == pe ) goto _test_eof132; case 132: switch( (*p) ) { case 95: goto tr177; case 116: goto tr227; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st133: if ( ++p == pe ) goto _test_eof133; case 133: switch( (*p) ) { case 95: goto tr177; case 97: goto st134; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st134: if ( ++p == pe ) goto _test_eof134; case 134: switch( (*p) ) { case 95: goto tr177; case 114: goto st135; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st135: if ( ++p == pe ) goto _test_eof135; case 135: switch( (*p) ) { case 95: goto tr177; case 103: goto st136; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; st136: if ( ++p == pe ) goto _test_eof136; case 136: switch( (*p) ) { case 95: goto tr177; case 115: goto tr231; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr177; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr177; } else goto tr177; goto tr188; tr232: #line 900 "rlscan.rl" {te = p+1;{ token( RE_Char, ts, te ); }} goto st137; tr233: #line 895 "rlscan.rl" {te = p+1;{ scan_error() << "unterminated OR literal" << endl; }} goto st137; tr234: #line 890 "rlscan.rl" {te = p+1;{ token( RE_Dash, 0, 0 ); }} goto st137; tr236: #line 893 "rlscan.rl" {te = p+1;{ token( RE_SqClose ); {cs = stack[--top];goto _again;} }} goto st137; tr237: #line 900 "rlscan.rl" {te = p;p--;{ token( RE_Char, ts, te ); }} goto st137; tr238: #line 887 "rlscan.rl" {te = p+1;{ token( RE_Char, ts+1, te ); }} goto st137; tr239: #line 886 "rlscan.rl" {te = p+1;{ updateCol(); }} goto st137; tr240: #line 878 "rlscan.rl" {te = p+1;{ token( RE_Char, '\0' ); }} goto st137; tr241: #line 879 "rlscan.rl" {te = p+1;{ token( RE_Char, '\a' ); }} goto st137; tr242: #line 880 "rlscan.rl" {te = p+1;{ token( RE_Char, '\b' ); }} goto st137; tr243: #line 884 "rlscan.rl" {te = p+1;{ token( RE_Char, '\f' ); }} goto st137; tr244: #line 882 "rlscan.rl" {te = p+1;{ token( RE_Char, '\n' ); }} goto st137; tr245: #line 885 "rlscan.rl" {te = p+1;{ token( RE_Char, '\r' ); }} goto st137; tr246: #line 881 "rlscan.rl" {te = p+1;{ token( RE_Char, '\t' ); }} goto st137; tr247: #line 883 "rlscan.rl" {te = p+1;{ token( RE_Char, '\v' ); }} goto st137; st137: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof137; case 137: #line 1 "NONE" {ts = p;} #line 3856 "rlscan.cpp" switch( (*p) ) { case 0: goto tr233; case 45: goto tr234; case 92: goto st138; case 93: goto tr236; } goto tr232; st138: if ( ++p == pe ) goto _test_eof138; case 138: switch( (*p) ) { case 10: goto tr239; case 48: goto tr240; case 97: goto tr241; case 98: goto tr242; case 102: goto tr243; case 110: goto tr244; case 114: goto tr245; case 116: goto tr246; case 118: goto tr247; } goto tr238; tr248: #line 935 "rlscan.rl" {te = p+1;{ token( RE_Char, ts, te ); }} goto st139; tr249: #line 930 "rlscan.rl" {te = p+1;{ scan_error() << "unterminated regular expression" << endl; }} goto st139; tr250: #line 925 "rlscan.rl" {te = p+1;{ token( RE_Star ); }} goto st139; tr251: #line 924 "rlscan.rl" {te = p+1;{ token( RE_Dot ); }} goto st139; tr255: #line 918 "rlscan.rl" {te = p;p--;{ token( RE_Slash, ts, te ); {goto st146;} }} goto st139; tr256: #line 918 "rlscan.rl" {te = p+1;{ token( RE_Slash, ts, te ); {goto st146;} }} goto st139; tr257: #line 927 "rlscan.rl" {te = p;p--;{ token( RE_SqOpen ); {stack[top++] = 139; goto st137;} }} goto st139; tr258: #line 928 "rlscan.rl" {te = p+1;{ token( RE_SqOpenNeg ); {stack[top++] = 139; goto st137;} }} goto st139; tr259: #line 935 "rlscan.rl" {te = p;p--;{ token( RE_Char, ts, te ); }} goto st139; tr260: #line 915 "rlscan.rl" {te = p+1;{ token( RE_Char, ts+1, te ); }} goto st139; tr261: #line 914 "rlscan.rl" {te = p+1;{ updateCol(); }} goto st139; tr262: #line 906 "rlscan.rl" {te = p+1;{ token( RE_Char, '\0' ); }} goto st139; tr263: #line 907 "rlscan.rl" {te = p+1;{ token( RE_Char, '\a' ); }} goto st139; tr264: #line 908 "rlscan.rl" {te = p+1;{ token( RE_Char, '\b' ); }} goto st139; tr265: #line 912 "rlscan.rl" {te = p+1;{ token( RE_Char, '\f' ); }} goto st139; tr266: #line 910 "rlscan.rl" {te = p+1;{ token( RE_Char, '\n' ); }} goto st139; tr267: #line 913 "rlscan.rl" {te = p+1;{ token( RE_Char, '\r' ); }} goto st139; tr268: #line 909 "rlscan.rl" {te = p+1;{ token( RE_Char, '\t' ); }} goto st139; tr269: #line 911 "rlscan.rl" {te = p+1;{ token( RE_Char, '\v' ); }} goto st139; st139: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof139; case 139: #line 1 "NONE" {ts = p;} #line 3972 "rlscan.cpp" switch( (*p) ) { case 0: goto tr249; case 42: goto tr250; case 46: goto tr251; case 47: goto st140; case 91: goto st141; case 92: goto st142; } goto tr248; st140: if ( ++p == pe ) goto _test_eof140; case 140: if ( (*p) == 105 ) goto tr256; goto tr255; st141: if ( ++p == pe ) goto _test_eof141; case 141: if ( (*p) == 94 ) goto tr258; goto tr257; st142: if ( ++p == pe ) goto _test_eof142; case 142: switch( (*p) ) { case 10: goto tr261; case 48: goto tr262; case 97: goto tr263; case 98: goto tr264; case 102: goto tr265; case 110: goto tr266; case 114: goto tr267; case 116: goto tr268; case 118: goto tr269; } goto tr260; tr270: #line 944 "rlscan.rl" {te = p+1;{ scan_error() << "unterminated write statement" << endl; }} goto st143; tr273: #line 942 "rlscan.rl" {te = p+1;{ token( ';' ); {goto st146;} }} goto st143; tr275: #line 941 "rlscan.rl" {te = p;p--;{ updateCol(); }} goto st143; tr276: #line 940 "rlscan.rl" {te = p;p--;{ token( TK_Word, ts, te ); }} goto st143; st143: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof143; case 143: #line 1 "NONE" {ts = p;} #line 4038 "rlscan.cpp" switch( (*p) ) { case 0: goto tr270; case 32: goto st144; case 59: goto tr273; case 95: goto st145; } if ( (*p) < 65 ) { if ( 9 <= (*p) && (*p) <= 10 ) goto st144; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st145; } else goto st145; goto st0; st0: cs = 0; goto _out; st144: if ( ++p == pe ) goto _test_eof144; case 144: if ( (*p) == 32 ) goto st144; if ( 9 <= (*p) && (*p) <= 10 ) goto st144; goto tr275; st145: if ( ++p == pe ) goto _test_eof145; case 145: if ( (*p) == 95 ) goto st145; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st145; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st145; } else goto st145; goto tr276; tr45: #line 1121 "rlscan.rl" {{p = ((te))-1;}{ token( *ts ); }} goto st146; tr51: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } #line 1018 "rlscan.rl" {te = p+1;{ updateCol(); }} goto st146; tr55: #line 1005 "rlscan.rl" {{p = ((te))-1;}{ token( TK_UInt, ts, te ); }} goto st146; tr57: #line 1086 "rlscan.rl" {te = p+1;{ updateCol(); endSection(); {cs = stack[--top];goto _again;} }} goto st146; tr277: #line 1121 "rlscan.rl" {te = p+1;{ token( *ts ); }} goto st146; tr278: #line 1117 "rlscan.rl" {te = p+1;{ scan_error() << "unterminated ragel section" << endl; }} goto st146; tr280: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } #line 1095 "rlscan.rl" {te = p+1;{ updateCol(); if ( singleLineSpec ) { endSection(); {cs = stack[--top];goto _again;} } }} goto st146; tr289: #line 1015 "rlscan.rl" {te = p+1;{ token( RE_Slash ); {goto st139;} }} goto st146; tr311: #line 1103 "rlscan.rl" {te = p+1;{ if ( lastToken == KW_Export || lastToken == KW_Entry ) token( '{' ); else { token( '{' ); curly_count = 1; inlineBlockType = CurlyDelimited; if ( hostLang->lang == HostLang::Ruby ) {stack[top++] = 146; goto st52;} else {stack[top++] = 146; goto st95;} } }} goto st146; tr314: #line 1092 "rlscan.rl" {te = p;p--;{ updateCol(); }} goto st146; tr315: #line 1121 "rlscan.rl" {te = p;p--;{ token( *ts ); }} goto st146; tr316: #line 1010 "rlscan.rl" {te = p;p--;{ token( TK_Literal, ts, te ); }} goto st146; tr317: #line 1010 "rlscan.rl" {te = p+1;{ token( TK_Literal, ts, te ); }} goto st146; tr318: #line 1048 "rlscan.rl" {te = p+1;{ token( TK_AllGblError ); }} goto st146; tr319: #line 1032 "rlscan.rl" {te = p+1;{ token( TK_AllFromState ); }} goto st146; tr320: #line 1040 "rlscan.rl" {te = p+1;{ token( TK_AllEOF ); }} goto st146; tr321: #line 1067 "rlscan.rl" {te = p+1;{ token( TK_AllCond ); }} goto st146; tr322: #line 1056 "rlscan.rl" {te = p+1;{ token( TK_AllLocalError ); }} goto st146; tr323: #line 1024 "rlscan.rl" {te = p+1;{ token( TK_AllToState ); }} goto st146; tr324: #line 1049 "rlscan.rl" {te = p+1;{ token( TK_FinalGblError ); }} goto st146; tr325: #line 1033 "rlscan.rl" {te = p+1;{ token( TK_FinalFromState ); }} goto st146; tr326: #line 1041 "rlscan.rl" {te = p+1;{ token( TK_FinalEOF ); }} goto st146; tr327: #line 1068 "rlscan.rl" {te = p+1;{ token( TK_LeavingCond ); }} goto st146; tr328: #line 1057 "rlscan.rl" {te = p+1;{ token( TK_FinalLocalError ); }} goto st146; tr329: #line 1025 "rlscan.rl" {te = p+1;{ token( TK_FinalToState ); }} goto st146; tr330: #line 1071 "rlscan.rl" {te = p+1;{ token( TK_StarStar ); }} goto st146; tr331: #line 1072 "rlscan.rl" {te = p+1;{ token( TK_DashDash ); }} goto st146; tr332: #line 1073 "rlscan.rl" {te = p+1;{ token( TK_Arrow ); }} goto st146; tr333: #line 1070 "rlscan.rl" {te = p+1;{ token( TK_DotDot ); }} goto st146; tr334: #line 1005 "rlscan.rl" {te = p;p--;{ token( TK_UInt, ts, te ); }} goto st146; tr336: #line 1006 "rlscan.rl" {te = p;p--;{ token( TK_Hex, ts, te ); }} goto st146; tr337: #line 1084 "rlscan.rl" {te = p+1;{ token( TK_NameSep, ts, te ); }} goto st146; tr338: #line 1020 "rlscan.rl" {te = p+1;{ token( TK_ColonEquals ); }} goto st146; tr340: #line 1076 "rlscan.rl" {te = p;p--;{ token( TK_ColonGt ); }} goto st146; tr341: #line 1077 "rlscan.rl" {te = p+1;{ token( TK_ColonGtGt ); }} goto st146; tr342: #line 1050 "rlscan.rl" {te = p+1;{ token( TK_NotStartGblError ); }} goto st146; tr343: #line 1034 "rlscan.rl" {te = p+1;{ token( TK_NotStartFromState ); }} goto st146; tr344: #line 1042 "rlscan.rl" {te = p+1;{ token( TK_NotStartEOF ); }} goto st146; tr345: #line 1078 "rlscan.rl" {te = p+1;{ token( TK_LtColon ); }} goto st146; tr347: #line 1058 "rlscan.rl" {te = p+1;{ token( TK_NotStartLocalError ); }} goto st146; tr348: #line 1026 "rlscan.rl" {te = p+1;{ token( TK_NotStartToState ); }} goto st146; tr349: #line 1063 "rlscan.rl" {te = p;p--;{ token( TK_Middle ); }} goto st146; tr350: #line 1052 "rlscan.rl" {te = p+1;{ token( TK_MiddleGblError ); }} goto st146; tr351: #line 1036 "rlscan.rl" {te = p+1;{ token( TK_MiddleFromState ); }} goto st146; tr352: #line 1044 "rlscan.rl" {te = p+1;{ token( TK_MiddleEOF ); }} goto st146; tr353: #line 1060 "rlscan.rl" {te = p+1;{ token( TK_MiddleLocalError ); }} goto st146; tr354: #line 1028 "rlscan.rl" {te = p+1;{ token( TK_MiddleToState ); }} goto st146; tr355: #line 1074 "rlscan.rl" {te = p+1;{ token( TK_DoubleArrow ); }} goto st146; tr356: #line 1047 "rlscan.rl" {te = p+1;{ token( TK_StartGblError ); }} goto st146; tr357: #line 1031 "rlscan.rl" {te = p+1;{ token( TK_StartFromState ); }} goto st146; tr358: #line 1039 "rlscan.rl" {te = p+1;{ token( TK_StartEOF ); }} goto st146; tr359: #line 1066 "rlscan.rl" {te = p+1;{ token( TK_StartCond ); }} goto st146; tr360: #line 1055 "rlscan.rl" {te = p+1;{ token( TK_StartLocalError ); }} goto st146; tr361: #line 1023 "rlscan.rl" {te = p+1;{ token( TK_StartToState ); }} goto st146; tr362: #line 1051 "rlscan.rl" {te = p+1;{ token( TK_NotFinalGblError ); }} goto st146; tr363: #line 1035 "rlscan.rl" {te = p+1;{ token( TK_NotFinalFromState ); }} goto st146; tr364: #line 1043 "rlscan.rl" {te = p+1;{ token( TK_NotFinalEOF ); }} goto st146; tr365: #line 1059 "rlscan.rl" {te = p+1;{ token( TK_NotFinalLocalError ); }} goto st146; tr366: #line 1027 "rlscan.rl" {te = p+1;{ token( TK_NotFinalToState ); }} goto st146; tr367: #line 1 "NONE" { switch( act ) { case 88: {{p = ((te))-1;} token( KW_Machine ); } break; case 89: {{p = ((te))-1;} token( KW_Include ); } break; case 90: {{p = ((te))-1;} token( KW_Import ); } break; case 91: {{p = ((te))-1;} token( KW_Write ); {goto st143;} } break; case 92: {{p = ((te))-1;} token( KW_Action ); } break; case 93: {{p = ((te))-1;} token( KW_AlphType ); } break; case 94: {{p = ((te))-1;} token( KW_PrePush ); } break; case 95: {{p = ((te))-1;} token( KW_PostPop ); } break; case 96: {{p = ((te))-1;} token( KW_GetKey ); inlineBlockType = SemiTerminated; if ( hostLang->lang == HostLang::Ruby ) {stack[top++] = 146; goto st52;} else {stack[top++] = 146; goto st95;} } break; case 97: {{p = ((te))-1;} token( KW_Access ); inlineBlockType = SemiTerminated; if ( hostLang->lang == HostLang::Ruby ) {stack[top++] = 146; goto st52;} else {stack[top++] = 146; goto st95;} } break; case 98: {{p = ((te))-1;} token( KW_Variable ); inlineBlockType = SemiTerminated; if ( hostLang->lang == HostLang::Ruby ) {stack[top++] = 146; goto st52;} else {stack[top++] = 146; goto st95;} } break; case 99: {{p = ((te))-1;} token( KW_When ); } break; case 100: {{p = ((te))-1;} token( KW_InWhen ); } break; case 101: {{p = ((te))-1;} token( KW_OutWhen ); } break; case 102: {{p = ((te))-1;} token( KW_Eof ); } break; case 103: {{p = ((te))-1;} token( KW_Err ); } break; case 104: {{p = ((te))-1;} token( KW_Lerr ); } break; case 105: {{p = ((te))-1;} token( KW_To ); } break; case 106: {{p = ((te))-1;} token( KW_From ); } break; case 107: {{p = ((te))-1;} token( KW_Export ); } break; case 108: {{p = ((te))-1;} token( TK_Word, ts, te ); } break; } } goto st146; tr368: #line 1012 "rlscan.rl" {te = p;p--;{ token( RE_SqOpen ); {stack[top++] = 146; goto st137;} }} goto st146; tr369: #line 1013 "rlscan.rl" {te = p+1;{ token( RE_SqOpenNeg ); {stack[top++] = 146; goto st137;} }} goto st146; tr370: #line 1002 "rlscan.rl" {te = p;p--;{ token( TK_Word, ts, te ); }} goto st146; tr461: #line 1081 "rlscan.rl" {te = p+1;{ token( TK_BarStar ); }} goto st146; st146: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof146; case 146: #line 1 "NONE" {ts = p;} #line 4470 "rlscan.cpp" switch( (*p) ) { case 0: goto tr278; case 9: goto st147; case 10: goto tr280; case 13: goto st147; case 32: goto st147; case 34: goto tr281; case 35: goto tr282; case 36: goto st151; case 37: goto st152; case 39: goto tr285; case 42: goto st154; case 45: goto st155; case 46: goto st156; case 47: goto tr289; case 48: goto tr290; case 58: goto st160; case 60: goto st162; case 61: goto st164; case 62: goto st165; case 64: goto st166; case 91: goto st168; case 95: goto tr297; case 97: goto st169; case 101: goto st183; case 102: goto st190; case 103: goto st193; case 105: goto st198; case 108: goto st211; case 109: goto st214; case 111: goto st220; case 112: goto st226; case 116: goto st237; case 118: goto st238; case 119: goto st245; case 123: goto tr311; case 124: goto st251; case 125: goto tr313; } if ( (*p) < 65 ) { if ( 49 <= (*p) && (*p) <= 57 ) goto st158; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr277; st147: if ( ++p == pe ) goto _test_eof147; case 147: switch( (*p) ) { case 9: goto st147; case 13: goto st147; case 32: goto st147; } goto tr314; tr281: #line 1 "NONE" {te = p+1;} goto st148; st148: if ( ++p == pe ) goto _test_eof148; case 148: #line 4537 "rlscan.cpp" switch( (*p) ) { case 10: goto tr47; case 34: goto st149; case 92: goto st25; } goto st24; tr47: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st24; st24: if ( ++p == pe ) goto _test_eof24; case 24: #line 4556 "rlscan.cpp" switch( (*p) ) { case 10: goto tr47; case 34: goto st149; case 92: goto st25; } goto st24; st149: if ( ++p == pe ) goto _test_eof149; case 149: if ( (*p) == 105 ) goto tr317; goto tr316; st25: if ( ++p == pe ) goto _test_eof25; case 25: if ( (*p) == 10 ) goto tr47; goto st24; tr282: #line 1 "NONE" {te = p+1;} goto st150; st150: if ( ++p == pe ) goto _test_eof150; case 150: #line 4585 "rlscan.cpp" if ( (*p) == 10 ) goto tr51; goto st26; st26: if ( ++p == pe ) goto _test_eof26; case 26: if ( (*p) == 10 ) goto tr51; goto st26; st151: if ( ++p == pe ) goto _test_eof151; case 151: switch( (*p) ) { case 33: goto tr318; case 42: goto tr319; case 47: goto tr320; case 63: goto tr321; case 94: goto tr322; case 126: goto tr323; } goto tr315; st152: if ( ++p == pe ) goto _test_eof152; case 152: switch( (*p) ) { case 33: goto tr324; case 42: goto tr325; case 47: goto tr326; case 63: goto tr327; case 94: goto tr328; case 126: goto tr329; } goto tr315; tr285: #line 1 "NONE" {te = p+1;} goto st153; st153: if ( ++p == pe ) goto _test_eof153; case 153: #line 4630 "rlscan.cpp" switch( (*p) ) { case 10: goto tr53; case 39: goto st149; case 92: goto st28; } goto st27; tr53: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: #line 4649 "rlscan.cpp" switch( (*p) ) { case 10: goto tr53; case 39: goto st149; case 92: goto st28; } goto st27; st28: if ( ++p == pe ) goto _test_eof28; case 28: if ( (*p) == 10 ) goto tr53; goto st27; st154: if ( ++p == pe ) goto _test_eof154; case 154: if ( (*p) == 42 ) goto tr330; goto tr315; st155: if ( ++p == pe ) goto _test_eof155; case 155: switch( (*p) ) { case 45: goto tr331; case 62: goto tr332; } goto tr315; st156: if ( ++p == pe ) goto _test_eof156; case 156: if ( (*p) == 46 ) goto tr333; goto tr315; tr290: #line 1 "NONE" {te = p+1;} goto st157; st157: if ( ++p == pe ) goto _test_eof157; case 157: #line 4694 "rlscan.cpp" if ( (*p) == 120 ) goto st29; if ( 48 <= (*p) && (*p) <= 57 ) goto st158; goto tr334; st158: if ( ++p == pe ) goto _test_eof158; case 158: if ( 48 <= (*p) && (*p) <= 57 ) goto st158; goto tr334; st29: if ( ++p == pe ) goto _test_eof29; case 29: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st159; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st159; } else goto st159; goto tr55; st159: if ( ++p == pe ) goto _test_eof159; case 159: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st159; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st159; } else goto st159; goto tr336; st160: if ( ++p == pe ) goto _test_eof160; case 160: switch( (*p) ) { case 58: goto tr337; case 61: goto tr338; case 62: goto st161; } goto tr315; st161: if ( ++p == pe ) goto _test_eof161; case 161: if ( (*p) == 62 ) goto tr341; goto tr340; st162: if ( ++p == pe ) goto _test_eof162; case 162: switch( (*p) ) { case 33: goto tr342; case 42: goto tr343; case 47: goto tr344; case 58: goto tr345; case 62: goto st163; case 94: goto tr347; case 126: goto tr348; } goto tr315; st163: if ( ++p == pe ) goto _test_eof163; case 163: switch( (*p) ) { case 33: goto tr350; case 42: goto tr351; case 47: goto tr352; case 94: goto tr353; case 126: goto tr354; } goto tr349; st164: if ( ++p == pe ) goto _test_eof164; case 164: if ( (*p) == 62 ) goto tr355; goto tr315; st165: if ( ++p == pe ) goto _test_eof165; case 165: switch( (*p) ) { case 33: goto tr356; case 42: goto tr357; case 47: goto tr358; case 63: goto tr359; case 94: goto tr360; case 126: goto tr361; } goto tr315; st166: if ( ++p == pe ) goto _test_eof166; case 166: switch( (*p) ) { case 33: goto tr362; case 42: goto tr363; case 47: goto tr364; case 94: goto tr365; case 126: goto tr366; } goto tr315; tr297: #line 1 "NONE" {te = p+1;} #line 1002 "rlscan.rl" {act = 108;} goto st167; tr377: #line 1 "NONE" {te = p+1;} #line 975 "rlscan.rl" {act = 97;} goto st167; tr380: #line 1 "NONE" {te = p+1;} #line 959 "rlscan.rl" {act = 92;} goto st167; tr386: #line 1 "NONE" {te = p+1;} #line 960 "rlscan.rl" {act = 93;} goto st167; tr390: #line 1 "NONE" {te = p+1;} #line 994 "rlscan.rl" {act = 102;} goto st167; tr391: #line 1 "NONE" {te = p+1;} #line 995 "rlscan.rl" {act = 103;} goto st167; tr395: #line 1 "NONE" {te = p+1;} #line 999 "rlscan.rl" {act = 107;} goto st167; tr398: #line 1 "NONE" {te = p+1;} #line 998 "rlscan.rl" {act = 106;} goto st167; tr403: #line 1 "NONE" {te = p+1;} #line 967 "rlscan.rl" {act = 96;} goto st167; tr409: #line 1 "NONE" {te = p+1;} #line 954 "rlscan.rl" {act = 90;} goto st167; tr415: #line 1 "NONE" {te = p+1;} #line 953 "rlscan.rl" {act = 89;} goto st167; tr418: #line 1 "NONE" {te = p+1;} #line 992 "rlscan.rl" {act = 100;} goto st167; tr421: #line 1 "NONE" {te = p+1;} #line 996 "rlscan.rl" {act = 104;} goto st167; tr427: #line 1 "NONE" {te = p+1;} #line 952 "rlscan.rl" {act = 88;} goto st167; tr433: #line 1 "NONE" {te = p+1;} #line 993 "rlscan.rl" {act = 101;} goto st167; tr440: #line 1 "NONE" {te = p+1;} #line 962 "rlscan.rl" {act = 95;} goto st167; tr445: #line 1 "NONE" {te = p+1;} #line 961 "rlscan.rl" {act = 94;} goto st167; tr446: #line 1 "NONE" {te = p+1;} #line 997 "rlscan.rl" {act = 105;} goto st167; tr453: #line 1 "NONE" {te = p+1;} #line 983 "rlscan.rl" {act = 98;} goto st167; tr457: #line 1 "NONE" {te = p+1;} #line 991 "rlscan.rl" {act = 99;} goto st167; tr460: #line 1 "NONE" {te = p+1;} #line 955 "rlscan.rl" {act = 91;} goto st167; st167: if ( ++p == pe ) goto _test_eof167; case 167: #line 4938 "rlscan.cpp" if ( (*p) == 95 ) goto tr297; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr367; st168: if ( ++p == pe ) goto _test_eof168; case 168: if ( (*p) == 94 ) goto tr369; goto tr368; st169: if ( ++p == pe ) goto _test_eof169; case 169: switch( (*p) ) { case 95: goto tr297; case 99: goto st170; case 108: goto st177; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st170: if ( ++p == pe ) goto _test_eof170; case 170: switch( (*p) ) { case 95: goto tr297; case 99: goto st171; case 116: goto st174; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st171: if ( ++p == pe ) goto _test_eof171; case 171: switch( (*p) ) { case 95: goto tr297; case 101: goto st172; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st172: if ( ++p == pe ) goto _test_eof172; case 172: switch( (*p) ) { case 95: goto tr297; case 115: goto st173; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st173: if ( ++p == pe ) goto _test_eof173; case 173: switch( (*p) ) { case 95: goto tr297; case 115: goto tr377; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st174: if ( ++p == pe ) goto _test_eof174; case 174: switch( (*p) ) { case 95: goto tr297; case 105: goto st175; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st175: if ( ++p == pe ) goto _test_eof175; case 175: switch( (*p) ) { case 95: goto tr297; case 111: goto st176; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st176: if ( ++p == pe ) goto _test_eof176; case 176: switch( (*p) ) { case 95: goto tr297; case 110: goto tr380; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st177: if ( ++p == pe ) goto _test_eof177; case 177: switch( (*p) ) { case 95: goto tr297; case 112: goto st178; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st178: if ( ++p == pe ) goto _test_eof178; case 178: switch( (*p) ) { case 95: goto tr297; case 104: goto st179; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st179: if ( ++p == pe ) goto _test_eof179; case 179: switch( (*p) ) { case 95: goto tr297; case 116: goto st180; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st180: if ( ++p == pe ) goto _test_eof180; case 180: switch( (*p) ) { case 95: goto tr297; case 121: goto st181; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st181: if ( ++p == pe ) goto _test_eof181; case 181: switch( (*p) ) { case 95: goto tr297; case 112: goto st182; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st182: if ( ++p == pe ) goto _test_eof182; case 182: switch( (*p) ) { case 95: goto tr297; case 101: goto tr386; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st183: if ( ++p == pe ) goto _test_eof183; case 183: switch( (*p) ) { case 95: goto tr297; case 111: goto st184; case 114: goto st185; case 120: goto st186; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st184: if ( ++p == pe ) goto _test_eof184; case 184: switch( (*p) ) { case 95: goto tr297; case 102: goto tr390; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st185: if ( ++p == pe ) goto _test_eof185; case 185: switch( (*p) ) { case 95: goto tr297; case 114: goto tr391; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st186: if ( ++p == pe ) goto _test_eof186; case 186: switch( (*p) ) { case 95: goto tr297; case 112: goto st187; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st187: if ( ++p == pe ) goto _test_eof187; case 187: switch( (*p) ) { case 95: goto tr297; case 111: goto st188; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st188: if ( ++p == pe ) goto _test_eof188; case 188: switch( (*p) ) { case 95: goto tr297; case 114: goto st189; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st189: if ( ++p == pe ) goto _test_eof189; case 189: switch( (*p) ) { case 95: goto tr297; case 116: goto tr395; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st190: if ( ++p == pe ) goto _test_eof190; case 190: switch( (*p) ) { case 95: goto tr297; case 114: goto st191; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st191: if ( ++p == pe ) goto _test_eof191; case 191: switch( (*p) ) { case 95: goto tr297; case 111: goto st192; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st192: if ( ++p == pe ) goto _test_eof192; case 192: switch( (*p) ) { case 95: goto tr297; case 109: goto tr398; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st193: if ( ++p == pe ) goto _test_eof193; case 193: switch( (*p) ) { case 95: goto tr297; case 101: goto st194; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st194: if ( ++p == pe ) goto _test_eof194; case 194: switch( (*p) ) { case 95: goto tr297; case 116: goto st195; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st195: if ( ++p == pe ) goto _test_eof195; case 195: switch( (*p) ) { case 95: goto tr297; case 107: goto st196; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st196: if ( ++p == pe ) goto _test_eof196; case 196: switch( (*p) ) { case 95: goto tr297; case 101: goto st197; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st197: if ( ++p == pe ) goto _test_eof197; case 197: switch( (*p) ) { case 95: goto tr297; case 121: goto tr403; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st198: if ( ++p == pe ) goto _test_eof198; case 198: switch( (*p) ) { case 95: goto tr297; case 109: goto st199; case 110: goto st203; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st199: if ( ++p == pe ) goto _test_eof199; case 199: switch( (*p) ) { case 95: goto tr297; case 112: goto st200; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st200: if ( ++p == pe ) goto _test_eof200; case 200: switch( (*p) ) { case 95: goto tr297; case 111: goto st201; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st201: if ( ++p == pe ) goto _test_eof201; case 201: switch( (*p) ) { case 95: goto tr297; case 114: goto st202; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st202: if ( ++p == pe ) goto _test_eof202; case 202: switch( (*p) ) { case 95: goto tr297; case 116: goto tr409; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st203: if ( ++p == pe ) goto _test_eof203; case 203: switch( (*p) ) { case 95: goto tr297; case 99: goto st204; case 119: goto st208; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st204: if ( ++p == pe ) goto _test_eof204; case 204: switch( (*p) ) { case 95: goto tr297; case 108: goto st205; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st205: if ( ++p == pe ) goto _test_eof205; case 205: switch( (*p) ) { case 95: goto tr297; case 117: goto st206; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st206: if ( ++p == pe ) goto _test_eof206; case 206: switch( (*p) ) { case 95: goto tr297; case 100: goto st207; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st207: if ( ++p == pe ) goto _test_eof207; case 207: switch( (*p) ) { case 95: goto tr297; case 101: goto tr415; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st208: if ( ++p == pe ) goto _test_eof208; case 208: switch( (*p) ) { case 95: goto tr297; case 104: goto st209; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st209: if ( ++p == pe ) goto _test_eof209; case 209: switch( (*p) ) { case 95: goto tr297; case 101: goto st210; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st210: if ( ++p == pe ) goto _test_eof210; case 210: switch( (*p) ) { case 95: goto tr297; case 110: goto tr418; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st211: if ( ++p == pe ) goto _test_eof211; case 211: switch( (*p) ) { case 95: goto tr297; case 101: goto st212; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st212: if ( ++p == pe ) goto _test_eof212; case 212: switch( (*p) ) { case 95: goto tr297; case 114: goto st213; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st213: if ( ++p == pe ) goto _test_eof213; case 213: switch( (*p) ) { case 95: goto tr297; case 114: goto tr421; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st214: if ( ++p == pe ) goto _test_eof214; case 214: switch( (*p) ) { case 95: goto tr297; case 97: goto st215; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st215: if ( ++p == pe ) goto _test_eof215; case 215: switch( (*p) ) { case 95: goto tr297; case 99: goto st216; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st216: if ( ++p == pe ) goto _test_eof216; case 216: switch( (*p) ) { case 95: goto tr297; case 104: goto st217; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st217: if ( ++p == pe ) goto _test_eof217; case 217: switch( (*p) ) { case 95: goto tr297; case 105: goto st218; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st218: if ( ++p == pe ) goto _test_eof218; case 218: switch( (*p) ) { case 95: goto tr297; case 110: goto st219; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st219: if ( ++p == pe ) goto _test_eof219; case 219: switch( (*p) ) { case 95: goto tr297; case 101: goto tr427; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st220: if ( ++p == pe ) goto _test_eof220; case 220: switch( (*p) ) { case 95: goto tr297; case 117: goto st221; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st221: if ( ++p == pe ) goto _test_eof221; case 221: switch( (*p) ) { case 95: goto tr297; case 116: goto st222; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st222: if ( ++p == pe ) goto _test_eof222; case 222: switch( (*p) ) { case 95: goto tr297; case 119: goto st223; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st223: if ( ++p == pe ) goto _test_eof223; case 223: switch( (*p) ) { case 95: goto tr297; case 104: goto st224; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st224: if ( ++p == pe ) goto _test_eof224; case 224: switch( (*p) ) { case 95: goto tr297; case 101: goto st225; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st225: if ( ++p == pe ) goto _test_eof225; case 225: switch( (*p) ) { case 95: goto tr297; case 110: goto tr433; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st226: if ( ++p == pe ) goto _test_eof226; case 226: switch( (*p) ) { case 95: goto tr297; case 111: goto st227; case 114: goto st232; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st227: if ( ++p == pe ) goto _test_eof227; case 227: switch( (*p) ) { case 95: goto tr297; case 115: goto st228; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st228: if ( ++p == pe ) goto _test_eof228; case 228: switch( (*p) ) { case 95: goto tr297; case 116: goto st229; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st229: if ( ++p == pe ) goto _test_eof229; case 229: switch( (*p) ) { case 95: goto tr297; case 112: goto st230; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st230: if ( ++p == pe ) goto _test_eof230; case 230: switch( (*p) ) { case 95: goto tr297; case 111: goto st231; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st231: if ( ++p == pe ) goto _test_eof231; case 231: switch( (*p) ) { case 95: goto tr297; case 112: goto tr440; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st232: if ( ++p == pe ) goto _test_eof232; case 232: switch( (*p) ) { case 95: goto tr297; case 101: goto st233; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st233: if ( ++p == pe ) goto _test_eof233; case 233: switch( (*p) ) { case 95: goto tr297; case 112: goto st234; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st234: if ( ++p == pe ) goto _test_eof234; case 234: switch( (*p) ) { case 95: goto tr297; case 117: goto st235; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st235: if ( ++p == pe ) goto _test_eof235; case 235: switch( (*p) ) { case 95: goto tr297; case 115: goto st236; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st236: if ( ++p == pe ) goto _test_eof236; case 236: switch( (*p) ) { case 95: goto tr297; case 104: goto tr445; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st237: if ( ++p == pe ) goto _test_eof237; case 237: switch( (*p) ) { case 95: goto tr297; case 111: goto tr446; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st238: if ( ++p == pe ) goto _test_eof238; case 238: switch( (*p) ) { case 95: goto tr297; case 97: goto st239; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st239: if ( ++p == pe ) goto _test_eof239; case 239: switch( (*p) ) { case 95: goto tr297; case 114: goto st240; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st240: if ( ++p == pe ) goto _test_eof240; case 240: switch( (*p) ) { case 95: goto tr297; case 105: goto st241; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st241: if ( ++p == pe ) goto _test_eof241; case 241: switch( (*p) ) { case 95: goto tr297; case 97: goto st242; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 98 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st242: if ( ++p == pe ) goto _test_eof242; case 242: switch( (*p) ) { case 95: goto tr297; case 98: goto st243; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st243: if ( ++p == pe ) goto _test_eof243; case 243: switch( (*p) ) { case 95: goto tr297; case 108: goto st244; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st244: if ( ++p == pe ) goto _test_eof244; case 244: switch( (*p) ) { case 95: goto tr297; case 101: goto tr453; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st245: if ( ++p == pe ) goto _test_eof245; case 245: switch( (*p) ) { case 95: goto tr297; case 104: goto st246; case 114: goto st248; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st246: if ( ++p == pe ) goto _test_eof246; case 246: switch( (*p) ) { case 95: goto tr297; case 101: goto st247; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st247: if ( ++p == pe ) goto _test_eof247; case 247: switch( (*p) ) { case 95: goto tr297; case 110: goto tr457; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st248: if ( ++p == pe ) goto _test_eof248; case 248: switch( (*p) ) { case 95: goto tr297; case 105: goto st249; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st249: if ( ++p == pe ) goto _test_eof249; case 249: switch( (*p) ) { case 95: goto tr297; case 116: goto st250; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st250: if ( ++p == pe ) goto _test_eof250; case 250: switch( (*p) ) { case 95: goto tr297; case 101: goto tr460; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr297; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto tr297; } else goto tr297; goto tr370; st251: if ( ++p == pe ) goto _test_eof251; case 251: if ( (*p) == 42 ) goto tr461; goto tr315; tr313: #line 1 "NONE" {te = p+1;} goto st252; st252: if ( ++p == pe ) goto _test_eof252; case 252: #line 6374 "rlscan.cpp" if ( (*p) == 37 ) goto st30; goto tr315; st30: if ( ++p == pe ) goto _test_eof30; case 30: if ( (*p) == 37 ) goto tr57; goto tr45; tr58: #line 1146 "rlscan.rl" {{p = ((te))-1;}{ pass( *ts, 0, 0 ); }} goto st253; tr61: #line 1130 "rlscan.rl" {te = p+1;{ pass( IMP_Literal, ts, te ); }} goto st253; tr64: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } #line 1128 "rlscan.rl" {te = p+1;{ pass(); }} goto st253; tr463: #line 1146 "rlscan.rl" {te = p+1;{ pass( *ts, 0, 0 ); }} goto st253; tr464: #line 1145 "rlscan.rl" {te = p+1;} goto st253; tr474: #line 1144 "rlscan.rl" {te = p;p--;{ pass(); }} goto st253; tr475: #line 1146 "rlscan.rl" {te = p;p--;{ pass( *ts, 0, 0 ); }} goto st253; tr477: #line 1138 "rlscan.rl" {te = p;p--;{ updateCol(); singleLineSpec = true; startSection(); {stack[top++] = 253; goto st146;} }} goto st253; tr478: #line 1132 "rlscan.rl" {te = p+1;{ updateCol(); singleLineSpec = false; startSection(); {stack[top++] = 253; goto st146;} }} goto st253; tr479: #line 1127 "rlscan.rl" {te = p;p--;{ pass( IMP_UInt, ts, te ); }} goto st253; tr480: #line 1126 "rlscan.rl" {te = p;p--;{ pass( IMP_Word, ts, te ); }} goto st253; st253: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof253; case 253: #line 1 "NONE" {ts = p;} #line 6453 "rlscan.cpp" switch( (*p) ) { case 0: goto tr464; case 9: goto st254; case 10: goto tr466; case 32: goto st254; case 34: goto tr467; case 35: goto tr468; case 37: goto st257; case 39: goto tr470; case 47: goto tr471; case 95: goto st262; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st261; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st262; } else goto st262; goto tr463; tr466: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st254; st254: if ( ++p == pe ) goto _test_eof254; case 254: #line 6487 "rlscan.cpp" switch( (*p) ) { case 9: goto st254; case 10: goto tr466; case 32: goto st254; } goto tr474; tr467: #line 1 "NONE" {te = p+1;} goto st255; st255: if ( ++p == pe ) goto _test_eof255; case 255: #line 6502 "rlscan.cpp" switch( (*p) ) { case 10: goto tr60; case 34: goto tr61; case 92: goto st32; } goto st31; tr60: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st31; st31: if ( ++p == pe ) goto _test_eof31; case 31: #line 6521 "rlscan.cpp" switch( (*p) ) { case 10: goto tr60; case 34: goto tr61; case 92: goto st32; } goto st31; st32: if ( ++p == pe ) goto _test_eof32; case 32: if ( (*p) == 10 ) goto tr60; goto st31; tr468: #line 1 "NONE" {te = p+1;} goto st256; st256: if ( ++p == pe ) goto _test_eof256; case 256: #line 6543 "rlscan.cpp" if ( (*p) == 10 ) goto tr64; goto st33; st33: if ( ++p == pe ) goto _test_eof33; case 33: if ( (*p) == 10 ) goto tr64; goto st33; st257: if ( ++p == pe ) goto _test_eof257; case 257: if ( (*p) == 37 ) goto st258; goto tr475; st258: if ( ++p == pe ) goto _test_eof258; case 258: if ( (*p) == 123 ) goto tr478; goto tr477; tr470: #line 1 "NONE" {te = p+1;} goto st259; st259: if ( ++p == pe ) goto _test_eof259; case 259: #line 6576 "rlscan.cpp" switch( (*p) ) { case 10: goto tr66; case 39: goto tr61; case 92: goto st35; } goto st34; tr66: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st34; st34: if ( ++p == pe ) goto _test_eof34; case 34: #line 6595 "rlscan.cpp" switch( (*p) ) { case 10: goto tr66; case 39: goto tr61; case 92: goto st35; } goto st34; st35: if ( ++p == pe ) goto _test_eof35; case 35: if ( (*p) == 10 ) goto tr66; goto st34; tr471: #line 1 "NONE" {te = p+1;} goto st260; st260: if ( ++p == pe ) goto _test_eof260; case 260: #line 6617 "rlscan.cpp" switch( (*p) ) { case 10: goto tr69; case 47: goto tr61; case 92: goto st37; } goto st36; tr69: #line 641 "rlscan.rl" { lastnl = p; column = 0; line++; } goto st36; st36: if ( ++p == pe ) goto _test_eof36; case 36: #line 6636 "rlscan.cpp" switch( (*p) ) { case 10: goto tr69; case 47: goto tr61; case 92: goto st37; } goto st36; st37: if ( ++p == pe ) goto _test_eof37; case 37: if ( (*p) == 10 ) goto tr69; goto st36; st261: if ( ++p == pe ) goto _test_eof261; case 261: if ( 48 <= (*p) && (*p) <= 57 ) goto st261; goto tr479; st262: if ( ++p == pe ) goto _test_eof262; case 262: if ( (*p) == 95 ) goto st262; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st262; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st262; } else goto st262; goto tr480; } _test_eof38: cs = 38; goto _test_eof; _test_eof39: cs = 39; goto _test_eof; _test_eof40: cs = 40; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof41: cs = 41; goto _test_eof; _test_eof42: cs = 42; goto _test_eof; _test_eof43: cs = 43; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof44: cs = 44; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof45: cs = 45; goto _test_eof; _test_eof46: cs = 46; goto _test_eof; _test_eof47: cs = 47; goto _test_eof; _test_eof48: cs = 48; goto _test_eof; _test_eof49: cs = 49; goto _test_eof; _test_eof50: cs = 50; goto _test_eof; _test_eof51: cs = 51; goto _test_eof; _test_eof52: cs = 52; goto _test_eof; _test_eof53: cs = 53; goto _test_eof; _test_eof54: cs = 54; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof55: cs = 55; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof56: cs = 56; goto _test_eof; _test_eof11: cs = 11; goto _test_eof; _test_eof12: cs = 12; goto _test_eof; _test_eof57: cs = 57; goto _test_eof; _test_eof13: cs = 13; goto _test_eof; _test_eof14: cs = 14; goto _test_eof; _test_eof58: cs = 58; goto _test_eof; _test_eof59: cs = 59; goto _test_eof; _test_eof15: cs = 15; goto _test_eof; _test_eof60: cs = 60; goto _test_eof; _test_eof61: cs = 61; goto _test_eof; _test_eof62: cs = 62; goto _test_eof; _test_eof63: cs = 63; goto _test_eof; _test_eof64: cs = 64; goto _test_eof; _test_eof65: cs = 65; goto _test_eof; _test_eof66: cs = 66; goto _test_eof; _test_eof67: cs = 67; goto _test_eof; _test_eof68: cs = 68; goto _test_eof; _test_eof69: cs = 69; goto _test_eof; _test_eof70: cs = 70; goto _test_eof; _test_eof71: cs = 71; goto _test_eof; _test_eof72: cs = 72; goto _test_eof; _test_eof73: cs = 73; goto _test_eof; _test_eof74: cs = 74; goto _test_eof; _test_eof75: cs = 75; goto _test_eof; _test_eof76: cs = 76; goto _test_eof; _test_eof77: cs = 77; goto _test_eof; _test_eof78: cs = 78; goto _test_eof; _test_eof79: cs = 79; goto _test_eof; _test_eof80: cs = 80; goto _test_eof; _test_eof81: cs = 81; goto _test_eof; _test_eof82: cs = 82; goto _test_eof; _test_eof83: cs = 83; goto _test_eof; _test_eof84: cs = 84; goto _test_eof; _test_eof85: cs = 85; goto _test_eof; _test_eof86: cs = 86; goto _test_eof; _test_eof87: cs = 87; goto _test_eof; _test_eof88: cs = 88; goto _test_eof; _test_eof89: cs = 89; goto _test_eof; _test_eof90: cs = 90; goto _test_eof; _test_eof91: cs = 91; goto _test_eof; _test_eof92: cs = 92; goto _test_eof; _test_eof93: cs = 93; goto _test_eof; _test_eof94: cs = 94; goto _test_eof; _test_eof95: cs = 95; goto _test_eof; _test_eof96: cs = 96; goto _test_eof; _test_eof97: cs = 97; goto _test_eof; _test_eof16: cs = 16; goto _test_eof; _test_eof17: cs = 17; goto _test_eof; _test_eof98: cs = 98; goto _test_eof; _test_eof18: cs = 18; goto _test_eof; _test_eof19: cs = 19; goto _test_eof; _test_eof99: cs = 99; goto _test_eof; _test_eof20: cs = 20; goto _test_eof; _test_eof21: cs = 21; goto _test_eof; _test_eof22: cs = 22; goto _test_eof; _test_eof100: cs = 100; goto _test_eof; _test_eof101: cs = 101; goto _test_eof; _test_eof23: cs = 23; goto _test_eof; _test_eof102: cs = 102; goto _test_eof; _test_eof103: cs = 103; goto _test_eof; _test_eof104: cs = 104; goto _test_eof; _test_eof105: cs = 105; goto _test_eof; _test_eof106: cs = 106; goto _test_eof; _test_eof107: cs = 107; goto _test_eof; _test_eof108: cs = 108; goto _test_eof; _test_eof109: cs = 109; goto _test_eof; _test_eof110: cs = 110; goto _test_eof; _test_eof111: cs = 111; goto _test_eof; _test_eof112: cs = 112; goto _test_eof; _test_eof113: cs = 113; goto _test_eof; _test_eof114: cs = 114; goto _test_eof; _test_eof115: cs = 115; goto _test_eof; _test_eof116: cs = 116; goto _test_eof; _test_eof117: cs = 117; goto _test_eof; _test_eof118: cs = 118; goto _test_eof; _test_eof119: cs = 119; goto _test_eof; _test_eof120: cs = 120; goto _test_eof; _test_eof121: cs = 121; goto _test_eof; _test_eof122: cs = 122; goto _test_eof; _test_eof123: cs = 123; goto _test_eof; _test_eof124: cs = 124; goto _test_eof; _test_eof125: cs = 125; goto _test_eof; _test_eof126: cs = 126; goto _test_eof; _test_eof127: cs = 127; goto _test_eof; _test_eof128: cs = 128; goto _test_eof; _test_eof129: cs = 129; goto _test_eof; _test_eof130: cs = 130; goto _test_eof; _test_eof131: cs = 131; goto _test_eof; _test_eof132: cs = 132; goto _test_eof; _test_eof133: cs = 133; goto _test_eof; _test_eof134: cs = 134; goto _test_eof; _test_eof135: cs = 135; goto _test_eof; _test_eof136: cs = 136; goto _test_eof; _test_eof137: cs = 137; goto _test_eof; _test_eof138: cs = 138; goto _test_eof; _test_eof139: cs = 139; goto _test_eof; _test_eof140: cs = 140; goto _test_eof; _test_eof141: cs = 141; goto _test_eof; _test_eof142: cs = 142; goto _test_eof; _test_eof143: cs = 143; goto _test_eof; _test_eof144: cs = 144; goto _test_eof; _test_eof145: cs = 145; goto _test_eof; _test_eof146: cs = 146; goto _test_eof; _test_eof147: cs = 147; goto _test_eof; _test_eof148: cs = 148; goto _test_eof; _test_eof24: cs = 24; goto _test_eof; _test_eof149: cs = 149; goto _test_eof; _test_eof25: cs = 25; goto _test_eof; _test_eof150: cs = 150; goto _test_eof; _test_eof26: cs = 26; goto _test_eof; _test_eof151: cs = 151; goto _test_eof; _test_eof152: cs = 152; goto _test_eof; _test_eof153: cs = 153; goto _test_eof; _test_eof27: cs = 27; goto _test_eof; _test_eof28: cs = 28; goto _test_eof; _test_eof154: cs = 154; goto _test_eof; _test_eof155: cs = 155; goto _test_eof; _test_eof156: cs = 156; goto _test_eof; _test_eof157: cs = 157; goto _test_eof; _test_eof158: cs = 158; goto _test_eof; _test_eof29: cs = 29; goto _test_eof; _test_eof159: cs = 159; goto _test_eof; _test_eof160: cs = 160; goto _test_eof; _test_eof161: cs = 161; goto _test_eof; _test_eof162: cs = 162; goto _test_eof; _test_eof163: cs = 163; goto _test_eof; _test_eof164: cs = 164; goto _test_eof; _test_eof165: cs = 165; goto _test_eof; _test_eof166: cs = 166; goto _test_eof; _test_eof167: cs = 167; goto _test_eof; _test_eof168: cs = 168; goto _test_eof; _test_eof169: cs = 169; goto _test_eof; _test_eof170: cs = 170; goto _test_eof; _test_eof171: cs = 171; goto _test_eof; _test_eof172: cs = 172; goto _test_eof; _test_eof173: cs = 173; goto _test_eof; _test_eof174: cs = 174; goto _test_eof; _test_eof175: cs = 175; goto _test_eof; _test_eof176: cs = 176; goto _test_eof; _test_eof177: cs = 177; goto _test_eof; _test_eof178: cs = 178; goto _test_eof; _test_eof179: cs = 179; goto _test_eof; _test_eof180: cs = 180; goto _test_eof; _test_eof181: cs = 181; goto _test_eof; _test_eof182: cs = 182; goto _test_eof; _test_eof183: cs = 183; goto _test_eof; _test_eof184: cs = 184; goto _test_eof; _test_eof185: cs = 185; goto _test_eof; _test_eof186: cs = 186; goto _test_eof; _test_eof187: cs = 187; goto _test_eof; _test_eof188: cs = 188; goto _test_eof; _test_eof189: cs = 189; goto _test_eof; _test_eof190: cs = 190; goto _test_eof; _test_eof191: cs = 191; goto _test_eof; _test_eof192: cs = 192; goto _test_eof; _test_eof193: cs = 193; goto _test_eof; _test_eof194: cs = 194; goto _test_eof; _test_eof195: cs = 195; goto _test_eof; _test_eof196: cs = 196; goto _test_eof; _test_eof197: cs = 197; goto _test_eof; _test_eof198: cs = 198; goto _test_eof; _test_eof199: cs = 199; goto _test_eof; _test_eof200: cs = 200; goto _test_eof; _test_eof201: cs = 201; goto _test_eof; _test_eof202: cs = 202; goto _test_eof; _test_eof203: cs = 203; goto _test_eof; _test_eof204: cs = 204; goto _test_eof; _test_eof205: cs = 205; goto _test_eof; _test_eof206: cs = 206; goto _test_eof; _test_eof207: cs = 207; goto _test_eof; _test_eof208: cs = 208; goto _test_eof; _test_eof209: cs = 209; goto _test_eof; _test_eof210: cs = 210; goto _test_eof; _test_eof211: cs = 211; goto _test_eof; _test_eof212: cs = 212; goto _test_eof; _test_eof213: cs = 213; goto _test_eof; _test_eof214: cs = 214; goto _test_eof; _test_eof215: cs = 215; goto _test_eof; _test_eof216: cs = 216; goto _test_eof; _test_eof217: cs = 217; goto _test_eof; _test_eof218: cs = 218; goto _test_eof; _test_eof219: cs = 219; goto _test_eof; _test_eof220: cs = 220; goto _test_eof; _test_eof221: cs = 221; goto _test_eof; _test_eof222: cs = 222; goto _test_eof; _test_eof223: cs = 223; goto _test_eof; _test_eof224: cs = 224; goto _test_eof; _test_eof225: cs = 225; goto _test_eof; _test_eof226: cs = 226; goto _test_eof; _test_eof227: cs = 227; goto _test_eof; _test_eof228: cs = 228; goto _test_eof; _test_eof229: cs = 229; goto _test_eof; _test_eof230: cs = 230; goto _test_eof; _test_eof231: cs = 231; goto _test_eof; _test_eof232: cs = 232; goto _test_eof; _test_eof233: cs = 233; goto _test_eof; _test_eof234: cs = 234; goto _test_eof; _test_eof235: cs = 235; goto _test_eof; _test_eof236: cs = 236; goto _test_eof; _test_eof237: cs = 237; goto _test_eof; _test_eof238: cs = 238; goto _test_eof; _test_eof239: cs = 239; goto _test_eof; _test_eof240: cs = 240; goto _test_eof; _test_eof241: cs = 241; goto _test_eof; _test_eof242: cs = 242; goto _test_eof; _test_eof243: cs = 243; goto _test_eof; _test_eof244: cs = 244; goto _test_eof; _test_eof245: cs = 245; goto _test_eof; _test_eof246: cs = 246; goto _test_eof; _test_eof247: cs = 247; goto _test_eof; _test_eof248: cs = 248; goto _test_eof; _test_eof249: cs = 249; goto _test_eof; _test_eof250: cs = 250; goto _test_eof; _test_eof251: cs = 251; goto _test_eof; _test_eof252: cs = 252; goto _test_eof; _test_eof30: cs = 30; goto _test_eof; _test_eof253: cs = 253; goto _test_eof; _test_eof254: cs = 254; goto _test_eof; _test_eof255: cs = 255; goto _test_eof; _test_eof31: cs = 31; goto _test_eof; _test_eof32: cs = 32; goto _test_eof; _test_eof256: cs = 256; goto _test_eof; _test_eof33: cs = 33; goto _test_eof; _test_eof257: cs = 257; goto _test_eof; _test_eof258: cs = 258; goto _test_eof; _test_eof259: cs = 259; goto _test_eof; _test_eof34: cs = 34; goto _test_eof; _test_eof35: cs = 35; goto _test_eof; _test_eof260: cs = 260; goto _test_eof; _test_eof36: cs = 36; goto _test_eof; _test_eof37: cs = 37; goto _test_eof; _test_eof261: cs = 261; goto _test_eof; _test_eof262: cs = 262; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 39: goto tr82; case 40: goto tr83; case 1: goto tr0; case 2: goto tr0; case 41: goto tr83; case 42: goto tr85; case 43: goto tr83; case 3: goto tr0; case 4: goto tr0; case 44: goto tr83; case 5: goto tr0; case 6: goto tr0; case 7: goto tr0; case 45: goto tr87; case 46: goto tr88; case 47: goto tr89; case 48: goto tr89; case 49: goto tr89; case 50: goto tr89; case 51: goto tr89; case 53: goto tr113; case 54: goto tr114; case 8: goto tr14; case 9: goto tr14; case 55: goto tr114; case 10: goto tr14; case 56: goto tr114; case 11: goto tr14; case 12: goto tr14; case 57: goto tr114; case 13: goto tr14; case 14: goto tr14; case 58: goto tr115; case 59: goto tr115; case 15: goto tr27; case 60: goto tr117; case 61: goto tr114; case 62: goto tr119; case 63: goto tr120; case 64: goto tr120; case 65: goto tr120; case 66: goto tr120; case 67: goto tr120; case 68: goto tr134; case 69: goto tr120; case 70: goto tr120; case 71: goto tr120; case 72: goto tr120; case 73: goto tr120; case 74: goto tr120; case 75: goto tr120; case 76: goto tr120; case 77: goto tr120; case 78: goto tr120; case 79: goto tr120; case 80: goto tr120; case 81: goto tr120; case 82: goto tr120; case 83: goto tr120; case 84: goto tr120; case 85: goto tr120; case 86: goto tr120; case 87: goto tr120; case 88: goto tr120; case 89: goto tr120; case 90: goto tr120; case 91: goto tr120; case 92: goto tr120; case 93: goto tr120; case 94: goto tr120; case 96: goto tr181; case 97: goto tr182; case 16: goto tr29; case 17: goto tr29; case 98: goto tr182; case 18: goto tr29; case 19: goto tr29; case 99: goto tr182; case 20: goto tr29; case 21: goto tr29; case 22: goto tr29; case 100: goto tr183; case 101: goto tr183; case 23: goto tr43; case 102: goto tr185; case 103: goto tr182; case 104: goto tr187; case 105: goto tr188; case 106: goto tr188; case 107: goto tr188; case 108: goto tr188; case 109: goto tr188; case 110: goto tr202; case 111: goto tr188; case 112: goto tr188; case 113: goto tr188; case 114: goto tr188; case 115: goto tr188; case 116: goto tr188; case 117: goto tr188; case 118: goto tr188; case 119: goto tr188; case 120: goto tr188; case 121: goto tr188; case 122: goto tr188; case 123: goto tr188; case 124: goto tr188; case 125: goto tr188; case 126: goto tr188; case 127: goto tr188; case 128: goto tr188; case 129: goto tr188; case 130: goto tr188; case 131: goto tr188; case 132: goto tr188; case 133: goto tr188; case 134: goto tr188; case 135: goto tr188; case 136: goto tr188; case 138: goto tr237; case 140: goto tr255; case 141: goto tr257; case 142: goto tr259; case 144: goto tr275; case 145: goto tr276; case 147: goto tr314; case 148: goto tr315; case 24: goto tr45; case 149: goto tr316; case 25: goto tr45; case 150: goto tr315; case 26: goto tr45; case 151: goto tr315; case 152: goto tr315; case 153: goto tr315; case 27: goto tr45; case 28: goto tr45; case 154: goto tr315; case 155: goto tr315; case 156: goto tr315; case 157: goto tr334; case 158: goto tr334; case 29: goto tr55; case 159: goto tr336; case 160: goto tr315; case 161: goto tr340; case 162: goto tr315; case 163: goto tr349; case 164: goto tr315; case 165: goto tr315; case 166: goto tr315; case 167: goto tr367; case 168: goto tr368; case 169: goto tr370; case 170: goto tr370; case 171: goto tr370; case 172: goto tr370; case 173: goto tr370; case 174: goto tr370; case 175: goto tr370; case 176: goto tr370; case 177: goto tr370; case 178: goto tr370; case 179: goto tr370; case 180: goto tr370; case 181: goto tr370; case 182: goto tr370; case 183: goto tr370; case 184: goto tr370; case 185: goto tr370; case 186: goto tr370; case 187: goto tr370; case 188: goto tr370; case 189: goto tr370; case 190: goto tr370; case 191: goto tr370; case 192: goto tr370; case 193: goto tr370; case 194: goto tr370; case 195: goto tr370; case 196: goto tr370; case 197: goto tr370; case 198: goto tr370; case 199: goto tr370; case 200: goto tr370; case 201: goto tr370; case 202: goto tr370; case 203: goto tr370; case 204: goto tr370; case 205: goto tr370; case 206: goto tr370; case 207: goto tr370; case 208: goto tr370; case 209: goto tr370; case 210: goto tr370; case 211: goto tr370; case 212: goto tr370; case 213: goto tr370; case 214: goto tr370; case 215: goto tr370; case 216: goto tr370; case 217: goto tr370; case 218: goto tr370; case 219: goto tr370; case 220: goto tr370; case 221: goto tr370; case 222: goto tr370; case 223: goto tr370; case 224: goto tr370; case 225: goto tr370; case 226: goto tr370; case 227: goto tr370; case 228: goto tr370; case 229: goto tr370; case 230: goto tr370; case 231: goto tr370; case 232: goto tr370; case 233: goto tr370; case 234: goto tr370; case 235: goto tr370; case 236: goto tr370; case 237: goto tr370; case 238: goto tr370; case 239: goto tr370; case 240: goto tr370; case 241: goto tr370; case 242: goto tr370; case 243: goto tr370; case 244: goto tr370; case 245: goto tr370; case 246: goto tr370; case 247: goto tr370; case 248: goto tr370; case 249: goto tr370; case 250: goto tr370; case 251: goto tr315; case 252: goto tr315; case 30: goto tr45; case 254: goto tr474; case 255: goto tr475; case 31: goto tr58; case 32: goto tr58; case 256: goto tr475; case 33: goto tr58; case 257: goto tr475; case 258: goto tr477; case 259: goto tr475; case 34: goto tr58; case 35: goto tr58; case 260: goto tr475; case 36: goto tr58; case 37: goto tr58; case 261: goto tr479; case 262: goto tr480; } } _out: {} } #line 1241 "rlscan.rl" /* Check if we failed. */ if ( cs == rlscan_error ) { /* Machine failed before finding a token. I'm not yet sure if this * is reachable. */ scan_error() << "scanner error" << endl; exit(1); } /* Decide if we need to preserve anything. */ char *preserve = ts; /* Now set up the prefix. */ if ( preserve == 0 ) have = 0; else { /* There is data that needs to be shifted over. */ have = pe - preserve; memmove( buf, preserve, have ); unsigned int shiftback = preserve - buf; if ( ts != 0 ) ts -= shiftback; te -= shiftback; preserve = buf; } } delete[] buf; } ragel-6.10/ragel/cdsplit.h0000664000175000017500000000420013065111230012346 00000000000000/* * Copyright 2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CDSPLIT_H #define _CDSPLIT_H #include "cdipgoto.h" class SplitCodeGen : public IpGotoCodeGen { public: SplitCodeGen( ostream &out ) : FsmCodeGen(out), IpGotoCodeGen(out) {} bool ptOutLabelUsed; std::ostream &PART_MAP(); std::ostream &EXIT_STATES( int partition ); std::ostream &PART_TRANS( int partition ); std::ostream &TRANS_GOTO( RedTransAp *trans, int level ); void GOTO_HEADER( RedStateAp *state, bool stateInPartition ); std::ostream &STATE_GOTOS( int partition ); std::ostream &PARTITION( int partition ); std::ostream &ALL_PARTITIONS(); void writeData(); void writeExec(); void writeParts(); void setLabelsNeeded( RedStateAp *fromState, GenInlineList *inlineList ); void setLabelsNeeded( RedStateAp *fromState, RedTransAp *trans ); void setLabelsNeeded(); int currentPartition; }; struct CSplitCodeGen : public SplitCodeGen, public CCodeGen { CSplitCodeGen( ostream &out ) : FsmCodeGen(out), SplitCodeGen(out), CCodeGen(out) {} }; /* * class DIpGotoCodeGen */ struct DSplitCodeGen : public SplitCodeGen, public DCodeGen { DSplitCodeGen( ostream &out ) : FsmCodeGen(out), SplitCodeGen(out), DCodeGen(out) {} }; /* * class D2SplitCodeGen */ struct D2SplitCodeGen : public SplitCodeGen, public D2CodeGen { D2SplitCodeGen( ostream &out ) : FsmCodeGen(out), SplitCodeGen(out), D2CodeGen(out) {} }; #endif ragel-6.10/ragel/parsetree.h0000664000175000017500000004254713065111230012716 00000000000000/* * Copyright 2001-2006 Adrian Thurston */ /* This file is part of Ragel. * * Ragel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ragel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Ragel; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PARSETREE_H #define _PARSETREE_H #include "ragel.h" #include "avlmap.h" #include "bstmap.h" #include "vector.h" #include "dlist.h" struct NameInst; /* Types of builtin machines. */ enum BuiltinMachine { BT_Any, BT_Ascii, BT_Extend, BT_Alpha, BT_Digit, BT_Alnum, BT_Lower, BT_Upper, BT_Cntrl, BT_Graph, BT_Print, BT_Punct, BT_Space, BT_Xdigit, BT_Lambda, BT_Empty }; struct ParseData; /* Leaf type. */ struct Literal; /* Tree nodes. */ struct Term; struct FactorWithAug; struct FactorWithRep; struct FactorWithNeg; struct Factor; struct Expression; struct Join; struct MachineDef; struct LongestMatch; struct LongestMatchPart; struct LmPartList; struct Range; struct LengthDef; /* Type of augmentation. Describes locations in the machine. */ enum AugType { /* Transition actions/priorities. */ at_start, at_all, at_finish, at_leave, /* Global error actions. */ at_start_gbl_error, at_all_gbl_error, at_final_gbl_error, at_not_start_gbl_error, at_not_final_gbl_error, at_middle_gbl_error, /* Local error actions. */ at_start_local_error, at_all_local_error, at_final_local_error, at_not_start_local_error, at_not_final_local_error, at_middle_local_error, /* To State Action embedding. */ at_start_to_state, at_all_to_state, at_final_to_state, at_not_start_to_state, at_not_final_to_state, at_middle_to_state, /* From State Action embedding. */ at_start_from_state, at_all_from_state, at_final_from_state, at_not_start_from_state, at_not_final_from_state, at_middle_from_state, /* EOF Action embedding. */ at_start_eof, at_all_eof, at_final_eof, at_not_start_eof, at_not_final_eof, at_middle_eof }; /* IMPORTANT: These must follow the same order as the state augs in AugType * since we will be using this to compose AugType. */ enum StateAugType { sat_start = 0, sat_all, sat_final, sat_not_start, sat_not_final, sat_middle }; struct Action; struct PriorDesc; struct RegExpr; struct ReItem; struct ReOrBlock; struct ReOrItem; struct ExplicitMachine; struct InlineItem; struct InlineList; /* Reference to a named state. */ typedef Vector NameRef; typedef Vector NameRefList; typedef Vector NameTargList; /* Structure for storing location of epsilon transitons. */ struct EpsilonLink { EpsilonLink( const InputLoc &loc, NameRef &target ) : loc(loc), target(target) { } InputLoc loc; NameRef target; }; struct Label { Label( const InputLoc &loc, char *data ) : loc(loc), data(data) { } InputLoc loc; char *data; }; /* Structrue represents an action assigned to some FactorWithAug node. The * factor with aug will keep an array of these. */ struct ParserAction { ParserAction( const InputLoc &loc, AugType type, int localErrKey, Action *action ) : loc(loc), type(type), localErrKey(localErrKey), action(action) { } InputLoc loc; AugType type; int localErrKey; Action *action; }; struct ConditionTest { ConditionTest( const InputLoc &loc, AugType type, Action *action, bool sense ) : loc(loc), type(type), action(action), sense(sense) { } InputLoc loc; AugType type; Action *action; bool sense; }; struct Token { char *data; int length; InputLoc loc; void append( const Token &other ); void set( const char *str, int len ); }; char *prepareLitString( const InputLoc &loc, const char *src, long length, long &resLen, bool &caseInsensitive ); /* Store the value and type of a priority augmentation. */ struct PriorityAug { PriorityAug( AugType type, int priorKey, int priorValue ) : type(type), priorKey(priorKey), priorValue(priorValue) { } AugType type; int priorKey; int priorValue; }; /* * A Variable Definition */ struct VarDef { VarDef( const char *name, MachineDef *machineDef ) : name(name), machineDef(machineDef), isExport(false) { } /* Parse tree traversal. */ FsmAp *walk( ParseData *pd ); void makeNameTree( const InputLoc &loc, ParseData *pd ); void resolveNameRefs( ParseData *pd ); const char *name; MachineDef *machineDef; bool isExport; }; /* * LongestMatch * * Wherever possible the item match will execute on the character. If not * possible the item match will execute on a lookahead character and either * hold the current char (if one away) or backup. * * How to handle the problem of backing up over a buffer break? * * Don't want to use pending out transitions for embedding item match because * the role of item match action is different: it may sometimes match on the * final transition, or may match on a lookahead character. * * Don't want to invent a new operator just for this. So just trail action * after machine, this means we can only use literal actions. * * The item action may * * What states of the machine will be final. The item actions that wrap around * on the last character will go straight to the start state. * * Some transitions will be lookahead transitions, they will hold the current * character. Crossing them with regular transitions must be restricted * because it does not make sense. The transition cannot simultaneously hold * and consume the current character. */ struct LongestMatchPart { LongestMatchPart( Join *join, Action *action, InputLoc &semiLoc, int longestMatchId ) : join(join), action(action), semiLoc(semiLoc), longestMatchId(longestMatchId), inLmSelect(false) { } InputLoc getLoc(); Join *join; Action *action; InputLoc semiLoc; Action *setActId; Action *actOnLast; Action *actOnNext; Action *actLagBehind; int longestMatchId; bool inLmSelect; LongestMatch *longestMatch; LongestMatchPart *prev, *next; }; /* Declare a new type so that ptreetypes.h need not include dlist.h. */ struct LmPartList : DList {}; struct LongestMatch { /* Construct with a list of joins */ LongestMatch( const InputLoc &loc, LmPartList *longestMatchList ) : loc(loc), longestMatchList(longestMatchList), name(0), lmSwitchHandlesError(false) { } /* Tree traversal. */ FsmAp *walk( ParseData *pd ); void makeNameTree( ParseData *pd ); void resolveNameRefs( ParseData *pd ); void transferScannerLeavingActions( FsmAp *graph ); void runLongestMatch( ParseData *pd, FsmAp *graph ); Action *newAction( ParseData *pd, const InputLoc &loc, const char *name, InlineList *inlineList ); void makeActions( ParseData *pd ); void findName( ParseData *pd ); void restart( FsmAp *graph, TransAp *trans ); InputLoc loc; LmPartList *longestMatchList; const char *name; Action *lmActSelect; bool lmSwitchHandlesError; LongestMatch *next, *prev; }; /* List of Expressions. */ typedef DList ExprList; struct MachineDef { enum Type { JoinType, LongestMatchType, LengthDefType }; MachineDef( Join *join ) : join(join), longestMatch(0), lengthDef(0), type(JoinType) {} MachineDef( LongestMatch *longestMatch ) : join(0), longestMatch(longestMatch), lengthDef(0), type(LongestMatchType) {} MachineDef( LengthDef *lengthDef ) : join(0), longestMatch(0), lengthDef(lengthDef), type(LengthDefType) {} FsmAp *walk( ParseData *pd ); void makeNameTree( ParseData *pd ); void resolveNameRefs( ParseData *pd ); Join *join; LongestMatch *longestMatch; LengthDef *lengthDef; Type type; }; /* * Join */ struct Join { /* Construct with the first expression. */ Join( Expression *expr ); Join( const InputLoc &loc, Expression *expr ); /* Tree traversal. */ FsmAp *walk( ParseData *pd ); FsmAp *walkJoin( ParseData *pd ); void makeNameTree( ParseData *pd ); void resolveNameRefs( ParseData *pd ); /* Data. */ InputLoc loc; ExprList exprList; }; /* * Expression */ struct Expression { enum Type { OrType, IntersectType, SubtractType, StrongSubtractType, TermType, BuiltinType }; /* Construct with an expression on the left and a term on the right. */ Expression( Expression *expression, Term *term, Type type ) : expression(expression), term(term), type(type), prev(this), next(this) { } /* Construct with only a term. */ Expression( Term *term ) : expression(0), term(term), type(TermType) , prev(this), next(this) { } /* Construct with a builtin type. */ Expression( BuiltinMachine builtin ) : expression(0), term(0), builtin(builtin), type(BuiltinType), prev(this), next(this) { } ~Expression(); /* Tree traversal. */ FsmAp *walk( ParseData *pd, bool lastInSeq = true ); void makeNameTree( ParseData *pd ); void resolveNameRefs( ParseData *pd ); /* Node data. */ Expression *expression; Term *term; BuiltinMachine builtin; Type type; Expression *prev, *next; }; /* * Term */ struct Term { enum Type { ConcatType, RightStartType, RightFinishType, LeftType, FactorWithAugType }; Term( Term *term, FactorWithAug *factorWithAug ) : term(term), factorWithAug(factorWithAug), type(ConcatType) { } Term( Term *term, FactorWithAug *factorWithAug, Type type ) : term(term), factorWithAug(factorWithAug), type(type) { } Term( FactorWithAug *factorWithAug ) : term(0), factorWithAug(factorWithAug), type(FactorWithAugType) { } ~Term(); FsmAp *walk( ParseData *pd, bool lastInSeq = true ); void makeNameTree( ParseData *pd ); void resolveNameRefs( ParseData *pd ); Term *term; FactorWithAug *factorWithAug; Type type; /* Priority descriptor for RightFinish type. */ PriorDesc priorDescs[2]; }; /* Third level of precedence. Augmenting nodes with actions and priorities. */ struct FactorWithAug { FactorWithAug( FactorWithRep *factorWithRep ) : priorDescs(0), factorWithRep(factorWithRep) { } ~FactorWithAug(); /* Tree traversal. */ FsmAp *walk( ParseData *pd ); void makeNameTree( ParseData *pd ); void resolveNameRefs( ParseData *pd ); void assignActions( ParseData *pd, FsmAp *graph, int *actionOrd ); void assignPriorities( FsmAp *graph, int *priorOrd ); void assignConditions( FsmAp *graph ); /* Actions and priorities assigned to the factor node. */ Vector actions; Vector priorityAugs; PriorDesc *priorDescs; Vector
\n" ); fgoto main; } }; '\n' { if ( single_line ) { write( "
\n" ); fgoto main; } }; # Word word { write( "" ); write( ts, te-ts ); write( "\n" ); }; # Decimal integer. integer { write( "" ); write( ts, te-ts ); write( "\n" ); }; # Hexidecimal integer. hex { write( "" ); write( ts, te-ts ); write( "\n" ); }; # Consume comments. '#' [^\n]* '\n'; # Single literal string. "'" ( [^'\\] | /\\./ )* "'" { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Double literal string. '"' ( [^"\\] | /\\./ )* '"' { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Or literal. '[' ( [^\]\\] | /\\./ )* ']' { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Regex Literal. '/' ( [^/\\] | /\\./ ) * '/' { write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }; # Open an inline block '{' { inline_depth = 1; write( "{" ); fgoto ilscan; }; punct { write( "" ); escapeXML( fc ); write( "\n" ); }; default; *|; # # Outside code. # main := |* "'" ( [^'\\] | /\\./ )* "'" => emit; '"' ( [^"\\] | /\\./ )* '"' => emit; '/*' { escapeXML( ts, te-ts ); fcall c_comment; }; '//' [^\n]* '\n' => emit; '%%{' { write( "
\n" ); single_line = false; fgoto rlscan; }; '%%' { write( "
\n" ); single_line = true; fgoto rlscan; }; default { escapeXML( *ts ); }; # EOF. EOF; *|; }%% %% write data nofinal; #define BUFSIZE 2048 int main() { std::ios::sync_with_stdio(false); int cs, act; char *ts, *te; int stack[1], top; static char inbuf[BUFSIZE]; bool single_line = false; int inline_depth = 0; %% write init; bool done = false; int have = 0; while ( !done ) { /* How much space is in the buffer? */ int space = BUFSIZE - have; if ( space == 0 ) { /* Buffer is full. */ cerr << "TOKEN TOO BIG" << endl; exit(1); } /* Read in a block. */ char *p = inbuf + have; cin.read( p, space ); int len = cin.gcount(); char *pe = p + len; char *eof = 0; /* Check for EOF. */ if ( len == 0 ) { eof = pe; done = true; } %% write exec; if ( cs == RagelScan_error ) { /* Machine failed before finding a token. */ cerr << "PARSE ERROR" << endl; exit(1); } if ( ts == 0 ) have = 0; else { /* There is a prefix to preserve, shift it over. */ have = pe - ts; memmove( inbuf, ts, have ); te = inbuf + (te-ts); ts = inbuf; } } return 0; } ragel-6.10/examples/format.c0000664000175000017500000002251113065122770012733 00000000000000 #line 1 "format.rl" /* * Partial printf implementation. */ #define BUFLEN 1024 #include typedef void (*WriteFunc)( char *data, int len ); struct format { char buf[BUFLEN+1]; int buflen; WriteFunc write; int flags; int width; int prec; int cs; }; void do_conv( struct format *fsm, char c ) { printf( "flags: %x\n", fsm->flags ); printf( "width: %i\n", fsm->width ); printf( "prec: %i\n", fsm->prec ); printf( "conv: %c\n", c ); printf( "\n" ); } #define FL_HASH 0x01 #define FL_ZERO 0x02 #define FL_DASH 0x04 #define FL_SPACE 0x08 #define FL_PLUS 0x10 #define FL_HAS_WIDTH 0x0100 #define FL_WIDTH_ARG 0x0200 #define FL_HAS_PREC 0x0400 #define FL_PREC_ARG 0x0800 #define FL_LEN_H 0x010000 #define FL_LEN_HH 0x020000 #define FL_LEN_L 0x040000 #define FL_LEN_LL 0x080000 #line 137 "format.rl" #line 55 "format.c" static const int format_start = 11; static const int format_first_final = 11; static const int format_error = 0; static const int format_en_main = 11; #line 140 "format.rl" void format_init( struct format *fsm ) { fsm->buflen = 0; #line 69 "format.c" { fsm->cs = format_start; } #line 145 "format.rl" } void format_execute( struct format *fsm, const char *data, int len, int isEof ) { const char *p = data; const char *pe = data + len; const char *eof = isEof ? pe : 0; #line 84 "format.c" { if ( p == pe ) goto _test_eof; switch ( fsm->cs ) { tr3: #line 113 "format.rl" { if ( fsm->buflen == BUFLEN ) { fsm->write( fsm->buf, fsm->buflen ); fsm->buflen = 0; } fsm->buf[fsm->buflen++] = (*p); } goto st11; tr10: #line 99 "format.rl" { do_conv( fsm, (*p) ); } goto st11; tr14: #line 63 "format.rl" { fsm->flags |= FL_HAS_WIDTH; } #line 99 "format.rl" { do_conv( fsm, (*p) ); } goto st11; tr19: #line 69 "format.rl" { fsm->flags |= FL_HAS_PREC; } #line 99 "format.rl" { do_conv( fsm, (*p) ); } goto st11; tr22: #line 86 "format.rl" { fsm->flags |= FL_LEN_H; } #line 99 "format.rl" { do_conv( fsm, (*p) ); } goto st11; tr24: #line 87 "format.rl" { fsm->flags |= FL_LEN_L; } #line 99 "format.rl" { do_conv( fsm, (*p) ); } goto st11; st11: if ( ++p == pe ) goto _test_eof11; case 11: #line 142 "format.c" if ( (*p) == 37 ) goto tr26; goto tr3; tr26: #line 51 "format.rl" { fsm->flags = 0; fsm->width = 0; fsm->prec = 0; } goto st1; st1: if ( ++p == pe ) goto _test_eof1; case 1: #line 158 "format.c" switch( (*p) ) { case 32: goto tr1; case 35: goto tr2; case 37: goto tr3; case 42: goto tr4; case 43: goto tr5; case 45: goto tr6; case 46: goto st4; case 48: goto tr8; case 88: goto tr10; case 104: goto st6; case 105: goto tr10; case 108: goto st8; case 115: goto tr10; case 117: goto tr10; case 120: goto tr10; } if ( (*p) < 99 ) { if ( 49 <= (*p) && (*p) <= 57 ) goto tr9; } else if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr10; } else goto tr10; goto tr0; tr0: #line 128 "format.rl" { printf("ERROR ON CHAR: 0x%x\n", (*p) ); } goto st0; #line 191 "format.c" st0: fsm->cs = 0; goto _out; tr1: #line 76 "format.rl" { fsm->flags |= FL_SPACE; } goto st2; tr2: #line 73 "format.rl" { fsm->flags |= FL_HASH; } goto st2; tr5: #line 77 "format.rl" { fsm->flags |= FL_PLUS; } goto st2; tr6: #line 75 "format.rl" { fsm->flags |= FL_DASH; } goto st2; tr8: #line 74 "format.rl" { fsm->flags |= FL_ZERO; } goto st2; st2: if ( ++p == pe ) goto _test_eof2; case 2: #line 219 "format.c" switch( (*p) ) { case 32: goto tr1; case 35: goto tr2; case 42: goto tr4; case 43: goto tr5; case 45: goto tr6; case 46: goto st4; case 48: goto tr8; case 88: goto tr10; case 104: goto st6; case 105: goto tr10; case 108: goto st8; case 115: goto tr10; case 117: goto tr10; case 120: goto tr10; } if ( (*p) < 99 ) { if ( 49 <= (*p) && (*p) <= 57 ) goto tr9; } else if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr10; } else goto tr10; goto tr0; tr4: #line 62 "format.rl" { fsm->flags |= FL_WIDTH_ARG; } goto st3; st3: if ( ++p == pe ) goto _test_eof3; case 3: #line 253 "format.c" switch( (*p) ) { case 46: goto tr13; case 88: goto tr14; case 104: goto tr15; case 105: goto tr14; case 108: goto tr16; case 115: goto tr14; case 117: goto tr14; case 120: goto tr14; } if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr14; } else if ( (*p) >= 99 ) goto tr14; goto tr0; tr13: #line 63 "format.rl" { fsm->flags |= FL_HAS_WIDTH; } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: #line 278 "format.c" switch( (*p) ) { case 42: goto tr17; case 88: goto tr19; case 104: goto tr20; case 105: goto tr19; case 108: goto tr21; case 115: goto tr19; case 117: goto tr19; case 120: goto tr19; } if ( (*p) < 99 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr18; } else if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr19; } else goto tr19; goto tr0; tr17: #line 68 "format.rl" { fsm->flags |= FL_PREC_ARG; } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: #line 306 "format.c" switch( (*p) ) { case 88: goto tr10; case 104: goto st6; case 105: goto tr10; case 108: goto st8; case 115: goto tr10; case 117: goto tr10; case 120: goto tr10; } if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr10; } else if ( (*p) >= 99 ) goto tr10; goto tr0; tr15: #line 63 "format.rl" { fsm->flags |= FL_HAS_WIDTH; } goto st6; tr20: #line 69 "format.rl" { fsm->flags |= FL_HAS_PREC; } goto st6; st6: if ( ++p == pe ) goto _test_eof6; case 6: #line 334 "format.c" switch( (*p) ) { case 88: goto tr22; case 104: goto tr23; case 105: goto tr22; case 115: goto tr22; case 117: goto tr22; case 120: goto tr22; } if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr22; } else if ( (*p) >= 99 ) goto tr22; goto tr0; tr23: #line 88 "format.rl" { fsm->flags |= FL_LEN_HH; } goto st7; tr25: #line 89 "format.rl" { fsm->flags |= FL_LEN_LL; } goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: #line 361 "format.c" switch( (*p) ) { case 88: goto tr10; case 105: goto tr10; case 115: goto tr10; case 117: goto tr10; case 120: goto tr10; } if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr10; } else if ( (*p) >= 99 ) goto tr10; goto tr0; tr16: #line 63 "format.rl" { fsm->flags |= FL_HAS_WIDTH; } goto st8; tr21: #line 69 "format.rl" { fsm->flags |= FL_HAS_PREC; } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: #line 387 "format.c" switch( (*p) ) { case 88: goto tr24; case 105: goto tr24; case 108: goto tr25; case 115: goto tr24; case 117: goto tr24; case 120: goto tr24; } if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr24; } else if ( (*p) >= 99 ) goto tr24; goto tr0; tr18: #line 67 "format.rl" { fsm->prec = 10 * fsm->prec + ((*p)-'0'); } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: #line 410 "format.c" switch( (*p) ) { case 88: goto tr19; case 104: goto tr20; case 105: goto tr19; case 108: goto tr21; case 115: goto tr19; case 117: goto tr19; case 120: goto tr19; } if ( (*p) < 99 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr18; } else if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr19; } else goto tr19; goto tr0; tr9: #line 61 "format.rl" { fsm->width = 10 * fsm->width + ((*p)-'0'); } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: #line 437 "format.c" switch( (*p) ) { case 46: goto tr13; case 88: goto tr14; case 104: goto tr15; case 105: goto tr14; case 108: goto tr16; case 115: goto tr14; case 117: goto tr14; case 120: goto tr14; } if ( (*p) < 99 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto tr9; } else if ( (*p) > 100 ) { if ( 111 <= (*p) && (*p) <= 112 ) goto tr14; } else goto tr14; goto tr0; } _test_eof11: fsm->cs = 11; goto _test_eof; _test_eof1: fsm->cs = 1; goto _test_eof; _test_eof2: fsm->cs = 2; goto _test_eof; _test_eof3: fsm->cs = 3; goto _test_eof; _test_eof4: fsm->cs = 4; goto _test_eof; _test_eof5: fsm->cs = 5; goto _test_eof; _test_eof6: fsm->cs = 6; goto _test_eof; _test_eof7: fsm->cs = 7; goto _test_eof; _test_eof8: fsm->cs = 8; goto _test_eof; _test_eof9: fsm->cs = 9; goto _test_eof; _test_eof10: fsm->cs = 10; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( fsm->cs ) { case 11: #line 121 "format.rl" { if ( fsm->buflen > 0 ) fsm->write( fsm->buf, fsm->buflen ); } break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: #line 125 "format.rl" { printf("EOF IN FORMAT\n"); } #line 128 "format.rl" { printf("ERROR ON CHAR: 0x%x\n", (*p) ); } break; #line 500 "format.c" } } _out: {} } #line 154 "format.rl" } int format_finish( struct format *fsm ) { if ( fsm->cs == format_error ) return -1; if ( fsm->cs >= format_first_final ) return 1; return 0; } #define INPUT_BUFSIZE 2048 struct format fsm; char buf[INPUT_BUFSIZE]; void write(char *data, int len ) { fwrite( data, 1, len, stdout ); } int main() { fsm.write = write; format_init( &fsm ); while ( 1 ) { int len = fread( buf, 1, INPUT_BUFSIZE, stdin ); int eof = len != INPUT_BUFSIZE; format_execute( &fsm, buf, len, eof ); if ( eof ) break; } if ( format_finish( &fsm ) <= 0 ) printf("FAIL\n"); return 0; } ragel-6.10/examples/gotocallret.rl0000664000175000017500000000415013065111230014141 00000000000000/* * Demonstrate the use of goto, call and return. This machine expects either a * lower case char or a digit as a command then a space followed by the command * arg. If the command is a char, then the arg must be an a string of chars. * If the command is a digit, then the arg must be a string of digits. This * choice is determined by action code, rather than though transition * desitinations. */ #include #include #include #include using namespace std; struct GotoCallRet { char comm; int cs, top, stack[32]; int init( ); int execute( const char *data, int len, bool isEof ); int finish( ); }; %%{ machine GotoCallRet; # Error machine, consumes to end of # line, then starts the main line over. garble_line := ( (any-'\n')*'\n' ) >{cout << "error: garbling line" << endl;} @{fgoto main;}; # Look for a string of alphas or of digits, # on anything else, hold the character and return. alp_comm := alpha+ $!{fhold;fret;}; dig_comm := digit+ $!{fhold;fret;}; # Choose which to machine to call into based on the command. action comm_arg { if ( comm >= 'a' ) fcall alp_comm; else fcall dig_comm; } # Specifies command string. Note that the arg is left out. command = ( [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n' ) @{cout << "correct command" << endl;}; # Any number of commands. If there is an # error anywhere, garble the line. main := command* $!{fhold;fgoto garble_line;}; }%% %% write data; int GotoCallRet::init( ) { %% write init; return 1; } int GotoCallRet::execute( const char *data, int len, bool isEof ) { const char *p = data; const char *pe = data + len; const char *eof = isEof ? pe : 0; %% write exec; if ( cs == GotoCallRet_error ) return -1; if ( cs >= GotoCallRet_first_final ) return 1; return 0; } #define BUFSIZE 1024 int main() { char buf[BUFSIZE]; GotoCallRet gcr; gcr.init(); while ( fgets( buf, sizeof(buf), stdin ) != 0 ) gcr.execute( buf, strlen(buf), false ); gcr.execute( 0, 0, true ); if ( gcr.cs < GotoCallRet_first_final ) cerr << "gotocallret: error: parsing input" << endl; return 0; } ragel-6.10/examples/concurrent.cpp0000664000175000017500000003520413065122770014170 00000000000000 #line 1 "concurrent.rl" /* * Show off concurrent abilities. */ #include #include #include using namespace std; #define BUFSIZE 2048 struct Concurrent { int cur_char; int start_word; int start_comment; int start_literal; int cs; int init( ); int execute( const char *data, int len, bool isEof ); int finish( ); }; #line 75 "concurrent.rl" #line 35 "concurrent.cpp" static const int Concurrent_start = 0; static const int Concurrent_first_final = 0; static const int Concurrent_error = -1; static const int Concurrent_en_main = 0; #line 78 "concurrent.rl" int Concurrent::init( ) { #line 48 "concurrent.cpp" { cs = Concurrent_start; } #line 82 "concurrent.rl" cur_char = 0; return 1; } int Concurrent::execute( const char *data, int len, bool isEof ) { const char *p = data; const char *pe = data + len; const char *eof = isEof ? pe : 0; #line 65 "concurrent.cpp" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr1: #line 30 "concurrent.rl" { cur_char += 1; } goto st0; tr5: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } goto st0; tr19: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } goto st0; tr46: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } goto st0; st0: if ( ++p == pe ) goto _test_eof0; case 0: #line 124 "concurrent.cpp" switch( (*p) ) { case 32: goto tr1; case 39: goto tr2; case 47: goto tr3; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr1; goto tr0; tr0: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st1; tr4: #line 30 "concurrent.rl" { cur_char += 1; } goto st1; tr18: #line 30 "concurrent.rl" { cur_char += 1; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } goto st1; tr45: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } goto st1; st1: if ( ++p == pe ) goto _test_eof1; case 1: #line 175 "concurrent.cpp" switch( (*p) ) { case 32: goto tr5; case 39: goto tr6; case 47: goto tr7; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr5; goto tr4; tr13: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st2; tr8: #line 30 "concurrent.rl" { cur_char += 1; } goto st2; tr2: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st2; tr6: #line 30 "concurrent.rl" { cur_char += 1; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st2; tr20: #line 30 "concurrent.rl" { cur_char += 1; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st2; tr50: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } goto st2; tr47: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st2; st2: if ( ++p == pe ) goto _test_eof2; case 2: #line 269 "concurrent.cpp" switch( (*p) ) { case 32: goto tr9; case 39: goto tr10; case 47: goto tr11; case 92: goto tr12; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr9; goto tr8; tr14: #line 30 "concurrent.rl" { cur_char += 1; } goto st3; tr9: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } goto st3; tr51: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } goto st3; st3: if ( ++p == pe ) goto _test_eof3; case 3: #line 316 "concurrent.cpp" switch( (*p) ) { case 32: goto tr14; case 39: goto tr15; case 47: goto tr16; case 92: goto tr17; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr14; goto tr13; tr15: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st4; tr10: #line 30 "concurrent.rl" { cur_char += 1; } goto st4; tr52: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: #line 357 "concurrent.cpp" switch( (*p) ) { case 32: goto tr19; case 39: goto tr20; case 47: goto tr21; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr19; goto tr18; tr3: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } #line 42 "concurrent.rl" { start_comment = cur_char; } goto st5; tr7: #line 30 "concurrent.rl" { cur_char += 1; } #line 42 "concurrent.rl" { start_comment = cur_char; } goto st5; tr21: #line 30 "concurrent.rl" { cur_char += 1; } #line 42 "concurrent.rl" { start_comment = cur_char; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } goto st5; tr48: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } #line 42 "concurrent.rl" { start_comment = cur_char; } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: #line 424 "concurrent.cpp" switch( (*p) ) { case 32: goto tr5; case 39: goto tr6; case 42: goto tr22; case 47: goto tr7; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr5; goto tr4; tr26: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st6; tr22: #line 30 "concurrent.rl" { cur_char += 1; } goto st6; tr40: #line 30 "concurrent.rl" { cur_char += 1; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } goto st6; st6: if ( ++p == pe ) goto _test_eof6; case 6: #line 465 "concurrent.cpp" switch( (*p) ) { case 32: goto tr23; case 39: goto tr24; case 42: goto tr25; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr23; goto tr22; tr27: #line 30 "concurrent.rl" { cur_char += 1; } goto st7; tr23: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } goto st7; tr41: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: #line 511 "concurrent.cpp" switch( (*p) ) { case 32: goto tr27; case 39: goto tr28; case 42: goto tr29; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr27; goto tr26; tr35: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st8; tr30: #line 30 "concurrent.rl" { cur_char += 1; } goto st8; tr28: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st8; tr24: #line 30 "concurrent.rl" { cur_char += 1; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st8; tr42: #line 30 "concurrent.rl" { cur_char += 1; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } #line 50 "concurrent.rl" { start_literal = cur_char; } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: #line 579 "concurrent.cpp" switch( (*p) ) { case 32: goto tr31; case 39: goto tr32; case 42: goto tr33; case 92: goto tr34; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr31; goto tr30; tr36: #line 30 "concurrent.rl" { cur_char += 1; } goto st9; tr31: #line 30 "concurrent.rl" { cur_char += 1; } #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: #line 610 "concurrent.cpp" switch( (*p) ) { case 32: goto tr36; case 39: goto tr37; case 42: goto tr38; case 92: goto tr39; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr36; goto tr35; tr37: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st10; tr32: #line 30 "concurrent.rl" { cur_char += 1; } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: #line 640 "concurrent.cpp" switch( (*p) ) { case 32: goto tr41; case 39: goto tr42; case 42: goto tr43; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr41; goto tr40; tr29: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st11; tr25: #line 30 "concurrent.rl" { cur_char += 1; } goto st11; tr43: #line 30 "concurrent.rl" { cur_char += 1; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } goto st11; st11: if ( ++p == pe ) goto _test_eof11; case 11: #line 680 "concurrent.cpp" switch( (*p) ) { case 32: goto tr23; case 39: goto tr24; case 42: goto tr25; case 47: goto tr44; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr23; goto tr22; tr44: #line 30 "concurrent.rl" { cur_char += 1; } goto st12; st12: if ( ++p == pe ) goto _test_eof12; case 12: #line 700 "concurrent.cpp" switch( (*p) ) { case 32: goto tr46; case 39: goto tr47; case 47: goto tr48; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr46; goto tr45; tr38: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st13; tr33: #line 30 "concurrent.rl" { cur_char += 1; } goto st13; st13: if ( ++p == pe ) goto _test_eof13; case 13: #line 729 "concurrent.cpp" switch( (*p) ) { case 32: goto tr31; case 39: goto tr32; case 42: goto tr33; case 47: goto tr49; case 92: goto tr34; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr31; goto tr30; tr49: #line 30 "concurrent.rl" { cur_char += 1; } goto st14; st14: if ( ++p == pe ) goto _test_eof14; case 14: #line 750 "concurrent.cpp" switch( (*p) ) { case 32: goto tr51; case 39: goto tr52; case 47: goto tr53; case 92: goto tr54; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr51; goto tr50; tr16: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } #line 42 "concurrent.rl" { start_comment = cur_char; } goto st15; tr11: #line 30 "concurrent.rl" { cur_char += 1; } #line 42 "concurrent.rl" { start_comment = cur_char; } goto st15; tr53: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } #line 42 "concurrent.rl" { start_comment = cur_char; } goto st15; st15: if ( ++p == pe ) goto _test_eof15; case 15: #line 803 "concurrent.cpp" switch( (*p) ) { case 32: goto tr9; case 39: goto tr10; case 42: goto tr30; case 47: goto tr11; case 92: goto tr12; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr9; goto tr8; tr17: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st16; tr12: #line 30 "concurrent.rl" { cur_char += 1; } goto st16; tr54: #line 30 "concurrent.rl" { cur_char += 1; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } goto st16; st16: if ( ++p == pe ) goto _test_eof16; case 16: #line 845 "concurrent.cpp" switch( (*p) ) { case 32: goto tr9; case 47: goto tr11; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr9; goto tr8; tr39: #line 30 "concurrent.rl" { cur_char += 1; } #line 34 "concurrent.rl" { start_word = cur_char; } goto st17; tr34: #line 30 "concurrent.rl" { cur_char += 1; } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: #line 873 "concurrent.cpp" switch( (*p) ) { case 32: goto tr31; case 42: goto tr33; } if ( 9 <= (*p) && (*p) <= 13 ) goto tr31; goto tr30; } _test_eof0: cs = 0; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof11: cs = 11; goto _test_eof; _test_eof12: cs = 12; goto _test_eof; _test_eof13: cs = 13; goto _test_eof; _test_eof14: cs = 14; goto _test_eof; _test_eof15: cs = 15; goto _test_eof; _test_eof16: cs = 16; goto _test_eof; _test_eof17: cs = 17; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 1: case 2: case 5: case 6: case 8: case 11: case 13: case 15: case 16: case 17: #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } break; case 12: case 14: #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } #line 45 "concurrent.rl" { cout << "comment: " << start_comment << " " << cur_char-1 << endl; } break; case 4: case 10: #line 37 "concurrent.rl" { cout << "word: " << start_word << " " << cur_char-1 << endl; } #line 53 "concurrent.rl" { cout << "literal: " << start_literal << " " << cur_char-1 << endl; } break; #line 947 "concurrent.cpp" } } } #line 93 "concurrent.rl" if ( cs == Concurrent_error ) return -1; if ( cs >= Concurrent_first_final ) return 1; return 0; } int Concurrent::finish( ) { if ( cs == Concurrent_error ) return -1; if ( cs >= Concurrent_first_final ) return 1; return 0; } Concurrent concurrent; char buf[BUFSIZE]; int main() { concurrent.init(); while ( 1 ) { int len = fread( buf, 1, BUFSIZE, stdin ); concurrent.execute( buf, len, len != BUFSIZE ); if ( len != BUFSIZE ) break; } if ( concurrent.finish() <= 0 ) cerr << "concurrent: error parsing input" << endl; return 0; } ragel-6.10/examples/Makefile.am0000664000175000017500000000456113065111230013325 00000000000000# # Copyright 2002-2009 Adrian Thurston # # This file is part of Ragel. # # Ragel is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Ragel is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ragel; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA RAGEL = ../ragel/ragel FLEX = flex RE2C = re2c noinst_PROGRAMS = \ atoi awkemu clang concurrent cppscan format gotocallret mailbox params \ pullscan rlscan statechart EXTRA_DIST = \ gotocallret.rl pullscan.rl concurrent.rl rlscan.rl statechart.rl \ params.rl clang.rl cppscan.rl format.rl awkemu.rl mailbox.rl atoi.rl gotocallret_SOURCES = gotocallret.cpp pullscan_SOURCES = pullscan.c concurrent_SOURCES = concurrent.cpp rlscan_SOURCES = rlscan.cpp statechart_SOURCES = statechart.cpp params_SOURCES = params.c clang_SOURCES = clang.c cppscan_SOURCES = cppscan.cpp format_SOURCES = format.c awkemu_SOURCES = awkemu.c mailbox_SOURCES = mailbox.cpp atoi_SOURCES = atoi.cpp gotocallret.cpp: gotocallret.rl $(RAGEL) -G2 -o gotocallret.cpp gotocallret.rl pullscan.c: pullscan.rl $(RAGEL) $(RAGEL) -G2 -o $@ pullscan.rl concurrent.cpp: concurrent.rl $(RAGEL) $(RAGEL) -G2 -o concurrent.cpp concurrent.rl rlscan.cpp: rlscan.rl $(RAGEL) -G2 -o rlscan.cpp rlscan.rl statechart.cpp: statechart.rl $(RAGEL) -G2 -o statechart.cpp statechart.rl params.c: params.rl $(RAGEL) -G2 -o params.c params.rl clang.c: clang.rl $(RAGEL) -G2 -o clang.c clang.rl cppscan.cpp: cppscan.rl $(RAGEL) -G2 -o $@ cppscan.rl format.c: format.rl $(RAGEL) -G2 -o format.c format.rl awkemu.c: awkemu.rl $(RAGEL) -G2 -o awkemu.c awkemu.rl mailbox.cpp: mailbox.rl $(RAGEL) -G2 -o mailbox.cpp mailbox.rl atoi.cpp: atoi.rl $(RAGEL) -G2 -o atoi.cpp atoi.rl ### lex-cppscan.cpp: cppscan.lex $(FLEX) -f -o $@ $< re2c-cppscan.cpp: cppscan.rec $(RE2C) -s $< > $@ example.cpp: example.rec $(RE2C) -s $< > $@ ragel-6.10/examples/statechart.rl0000664000175000017500000000333213065111230013765 00000000000000/* * Demonstrate the use of labels, the epsilon operator, and the join operator * for creating machines using the named state and transition list paradigm. * This implementes the same machine as the atoi example. */ #include #include #include #include using namespace std; struct StateChart { bool neg; int val; int cs; int init( ); int execute( const char *data, int len ); int finish( ); }; %%{ machine StateChart; action begin { neg = false; val = 0; } action see_neg { neg = true; } action add_digit { val = val * 10 + (fc - '0'); } action finish { if ( neg ) val = -1 * val; } atoi = ( start: ( '-' @see_neg ->om_num | '+' ->om_num | [0-9] @add_digit ->more_nums ), # One or more nums. om_num: ( [0-9] @add_digit ->more_nums ), # Zero ore more nums. more_nums: ( [0-9] @add_digit ->more_nums | '' -> final ) ) >begin %finish; main := ( atoi '\n' @{ cout << val << endl; } )*; }%% %% write data; int StateChart::init( ) { neg = false; val = false; %% write init; return 1; } int StateChart::execute( const char *data, int len ) { const char *p = data; const char *pe = data + len; %% write exec; if ( cs == StateChart_error ) return -1; if ( cs >= StateChart_first_final ) return 1; return 0; } int StateChart::finish( ) { if ( cs == StateChart_error ) return -1; if ( cs >= StateChart_first_final ) return 1; return 0; } #define BUFSIZE 1024 int main() { char buf[BUFSIZE]; StateChart atoi; atoi.init(); while ( fgets( buf, sizeof(buf), stdin ) != 0 ) { atoi.execute( buf, strlen(buf) ); } if ( atoi.finish() <= 0 ) cerr << "statechart: error: parsing input" << endl; return 0; } ragel-6.10/examples/rlscan.cpp0000664000175000017500000004240213065122770013266 00000000000000 #line 1 "rlscan.rl" /* * Lexes Ragel input files. */ #include #include #include #include using namespace std; void escapeXML( char *data ) { while ( *data != 0 ) { switch ( *data ) { case '<': cout << "<"; break; case '>': cout << ">"; break; case '&': cout << "&"; break; default: cout << *data; break; } data += 1; } } void escapeXML( char c ) { switch ( c ) { case '<': cout << "<"; break; case '>': cout << ">"; break; case '&': cout << "&"; break; default: cout << c; break; } } void escapeXML( char *data, int len ) { for ( char *end = data + len; data != end; data++ ) { switch ( *data ) { case '<': cout << "<"; break; case '>': cout << ">"; break; case '&': cout << "&"; break; default: cout << *data; break; } } } inline void write( const char *data ) { cout << data; } inline void write( char c ) { cout << c; } inline void write( char *data, int len ) { cout.write( data, len ); } #line 237 "rlscan.rl" #line 71 "rlscan.cpp" static const int RagelScan_start = 24; static const int RagelScan_error = 0; static const int RagelScan_en_c_comment = 6; static const int RagelScan_en_ilscan = 31; static const int RagelScan_en_rlscan = 35; static const int RagelScan_en_main = 24; #line 240 "rlscan.rl" #define BUFSIZE 2048 int main() { std::ios::sync_with_stdio(false); int cs, act; char *ts, *te; int stack[1], top; static char inbuf[BUFSIZE]; bool single_line = false; int inline_depth = 0; #line 98 "rlscan.cpp" { cs = RagelScan_start; top = 0; ts = 0; te = 0; act = 0; } #line 256 "rlscan.rl" bool done = false; int have = 0; while ( !done ) { /* How much space is in the buffer? */ int space = BUFSIZE - have; if ( space == 0 ) { /* Buffer is full. */ cerr << "TOKEN TOO BIG" << endl; exit(1); } /* Read in a block. */ char *p = inbuf + have; cin.read( p, space ); int len = cin.gcount(); char *pe = p + len; char *eof = 0; /* Check for EOF. */ if ( len == 0 ) { eof = pe; done = true; } #line 134 "rlscan.cpp" { if ( p == pe ) goto _test_eof; goto _resume; _again: switch ( cs ) { case 24: goto st24; case 25: goto st25; case 1: goto st1; case 2: goto st2; case 26: goto st26; case 27: goto st27; case 28: goto st28; case 3: goto st3; case 4: goto st4; case 29: goto st29; case 5: goto st5; case 6: goto st6; case 0: goto st0; case 7: goto st7; case 30: goto st30; case 31: goto st31; case 32: goto st32; case 8: goto st8; case 9: goto st9; case 33: goto st33; case 10: goto st10; case 11: goto st11; case 34: goto st34; case 12: goto st12; case 35: goto st35; case 36: goto st36; case 13: goto st13; case 14: goto st14; case 37: goto st37; case 15: goto st15; case 38: goto st38; case 16: goto st16; case 17: goto st17; case 39: goto st39; case 18: goto st18; case 19: goto st19; case 40: goto st40; case 41: goto st41; case 20: goto st20; case 42: goto st42; case 43: goto st43; case 44: goto st44; case 21: goto st21; case 22: goto st22; case 45: goto st45; case 23: goto st23; default: break; } if ( ++p == pe ) goto _test_eof; _resume: switch ( cs ) { tr0: #line 230 "rlscan.rl" {{p = ((te))-1;}{ escapeXML( *ts ); }} goto st24; tr2: #line 79 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); }} goto st24; tr5: #line 79 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); }} goto st24; tr8: #line 79 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); }} goto st24; tr40: #line 230 "rlscan.rl" {te = p+1;{ escapeXML( *ts ); }} goto st24; tr41: #line 235 "rlscan.rl" {te = p+1;} goto st24; tr46: #line 230 "rlscan.rl" {te = p;p--;{ escapeXML( *ts ); }} goto st24; tr48: #line 224 "rlscan.rl" {te = p;p--;{ write( "
\n" ); single_line = true; {goto st35;} }} goto st24; tr49: #line 218 "rlscan.rl" {te = p+1;{ write( "
\n" ); single_line = false; {goto st35;} }} goto st24; tr50: #line 211 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); {stack[top++] = 24;goto st6;} }} goto st24; st24: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof24; case 24: #line 1 "NONE" {ts = p;} #line 267 "rlscan.cpp" switch( (*p) ) { case 0: goto tr41; case 34: goto tr42; case 37: goto st26; case 39: goto tr44; case 47: goto tr45; } goto tr40; tr42: #line 1 "NONE" {te = p+1;} goto st25; st25: if ( ++p == pe ) goto _test_eof25; case 25: #line 284 "rlscan.cpp" switch( (*p) ) { case 34: goto tr2; case 92: goto st2; } goto st1; st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 34: goto tr2; case 92: goto st2; } goto st1; st2: if ( ++p == pe ) goto _test_eof2; case 2: goto st1; st26: if ( ++p == pe ) goto _test_eof26; case 26: if ( (*p) == 37 ) goto st27; goto tr46; st27: if ( ++p == pe ) goto _test_eof27; case 27: if ( (*p) == 123 ) goto tr49; goto tr48; tr44: #line 1 "NONE" {te = p+1;} goto st28; st28: if ( ++p == pe ) goto _test_eof28; case 28: #line 326 "rlscan.cpp" switch( (*p) ) { case 39: goto tr5; case 92: goto st4; } goto st3; st3: if ( ++p == pe ) goto _test_eof3; case 3: switch( (*p) ) { case 39: goto tr5; case 92: goto st4; } goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: goto st3; tr45: #line 1 "NONE" {te = p+1;} goto st29; st29: if ( ++p == pe ) goto _test_eof29; case 29: #line 354 "rlscan.cpp" switch( (*p) ) { case 42: goto tr50; case 47: goto st5; } goto tr46; st5: if ( ++p == pe ) goto _test_eof5; case 5: if ( (*p) == 10 ) goto tr8; goto st5; tr9: #line 76 "rlscan.rl" { escapeXML( (*p) ); } goto st6; st6: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof6; case 6: #line 377 "rlscan.cpp" switch( (*p) ) { case 0: goto st0; case 42: goto tr11; } goto tr9; st0: cs = 0; goto _out; tr11: #line 76 "rlscan.rl" { escapeXML( (*p) ); } goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: #line 394 "rlscan.cpp" switch( (*p) ) { case 0: goto st0; case 42: goto tr11; case 47: goto tr12; } goto tr9; tr12: #line 76 "rlscan.rl" { escapeXML( (*p) ); } #line 77 "rlscan.rl" { {cs = stack[--top];goto _again;} } goto st30; st30: if ( ++p == pe ) goto _test_eof30; case 30: #line 411 "rlscan.cpp" goto st0; tr13: #line 112 "rlscan.rl" {{p = ((te))-1;}{ escapeXML( *ts ); }} goto st31; tr15: #line 79 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); }} goto st31; tr18: #line 79 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); }} goto st31; tr21: #line 79 "rlscan.rl" {te = p+1;{ escapeXML( ts, te-ts ); }} goto st31; tr51: #line 112 "rlscan.rl" {te = p+1;{ escapeXML( *ts ); }} goto st31; tr55: #line 97 "rlscan.rl" {te = p+1;{ write( '{' ); inline_depth += 1; }} goto st31; tr56: #line 102 "rlscan.rl" {te = p+1;{ write( '}' ); /* If dropping down to the last } then return * to ragel code. */ if ( --inline_depth == 0 ) { write( "\n" ); {goto st35;} } }} goto st31; tr57: #line 112 "rlscan.rl" {te = p;p--;{ escapeXML( *ts ); }} goto st31; tr58: #line 91 "rlscan.rl" {te = p+1;{ write( "/*" ); {stack[top++] = 31;goto st6;} }} goto st31; st31: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof31; case 31: #line 1 "NONE" {ts = p;} #line 477 "rlscan.cpp" switch( (*p) ) { case 0: goto st0; case 34: goto tr52; case 39: goto tr53; case 47: goto tr54; case 123: goto tr55; case 125: goto tr56; } goto tr51; tr52: #line 1 "NONE" {te = p+1;} goto st32; st32: if ( ++p == pe ) goto _test_eof32; case 32: #line 495 "rlscan.cpp" switch( (*p) ) { case 34: goto tr15; case 92: goto st9; } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: switch( (*p) ) { case 34: goto tr15; case 92: goto st9; } goto st8; st9: if ( ++p == pe ) goto _test_eof9; case 9: goto st8; tr53: #line 1 "NONE" {te = p+1;} goto st33; st33: if ( ++p == pe ) goto _test_eof33; case 33: #line 523 "rlscan.cpp" switch( (*p) ) { case 39: goto tr18; case 92: goto st11; } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: switch( (*p) ) { case 39: goto tr18; case 92: goto st11; } goto st10; st11: if ( ++p == pe ) goto _test_eof11; case 11: goto st10; tr54: #line 1 "NONE" {te = p+1;} goto st34; st34: if ( ++p == pe ) goto _test_eof34; case 34: #line 551 "rlscan.cpp" switch( (*p) ) { case 42: goto tr58; case 47: goto st12; } goto tr57; st12: if ( ++p == pe ) goto _test_eof12; case 12: if ( (*p) == 10 ) goto tr21; goto st12; tr22: #line 193 "rlscan.rl" {{p = ((te))-1;}{ write( "" ); escapeXML( (*p) ); write( "\n" ); }} goto st35; tr24: #line 166 "rlscan.rl" {te = p+1;{ write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }} goto st35; tr27: #line 156 "rlscan.rl" {te = p+1;} goto st35; tr29: #line 159 "rlscan.rl" {te = p+1;{ write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }} goto st35; tr32: #line 180 "rlscan.rl" {te = p+1;{ write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }} goto st35; tr34: #line 142 "rlscan.rl" {{p = ((te))-1;}{ write( "" ); write( ts, te-ts ); write( "\n" ); }} goto st35; tr38: #line 173 "rlscan.rl" {te = p+1;{ write( "" ); escapeXML( ts, te-ts ); write( "\n" ); }} goto st35; tr39: #line 120 "rlscan.rl" {te = p+1;{ if ( !single_line ) { write( "
\n" ); {goto st24;} } }} goto st35; tr59: #line 199 "rlscan.rl" {te = p+1;} goto st35; tr60: #line 127 "rlscan.rl" {te = p+1;{ if ( single_line ) { write( "
\n" ); {goto st24;} } }} goto st35; tr61: #line 193 "rlscan.rl" {te = p+1;{ write( "" ); escapeXML( (*p) ); write( "\n" ); }} goto st35; tr70: #line 187 "rlscan.rl" {te = p+1;{ inline_depth = 1; write( "{" ); {goto st31;} }} goto st35; tr72: #line 193 "rlscan.rl" {te = p;p--;{ write( "" ); escapeXML( (*p) ); write( "\n" ); }} goto st35; tr73: #line 142 "rlscan.rl" {te = p;p--;{ write( "" ); write( ts, te-ts ); write( "\n" ); }} goto st35; tr75: #line 149 "rlscan.rl" {te = p;p--;{ write( "" ); write( ts, te-ts ); write( "\n" ); }} goto st35; tr76: #line 135 "rlscan.rl" {te = p;p--;{ write( "" ); write( ts, te-ts ); write( "\n" ); }} goto st35; st35: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof35; case 35: #line 1 "NONE" {ts = p;} #line 694 "rlscan.cpp" switch( (*p) ) { case 0: goto st0; case 10: goto tr60; case 34: goto tr62; case 35: goto tr63; case 39: goto tr64; case 47: goto tr65; case 48: goto tr66; case 91: goto tr69; case 95: goto st43; case 123: goto tr70; case 125: goto tr71; } if ( (*p) < 65 ) { if ( (*p) < 49 ) { if ( 33 <= (*p) && (*p) <= 46 ) goto tr61; } else if ( (*p) > 57 ) { if ( 58 <= (*p) && (*p) <= 64 ) goto tr61; } else goto st41; } else if ( (*p) > 90 ) { if ( (*p) < 97 ) { if ( 92 <= (*p) && (*p) <= 96 ) goto tr61; } else if ( (*p) > 122 ) { if ( 124 <= (*p) && (*p) <= 126 ) goto tr61; } else goto st43; } else goto st43; goto tr59; tr62: #line 1 "NONE" {te = p+1;} goto st36; st36: if ( ++p == pe ) goto _test_eof36; case 36: #line 737 "rlscan.cpp" switch( (*p) ) { case 34: goto tr24; case 92: goto st14; } goto st13; st13: if ( ++p == pe ) goto _test_eof13; case 13: switch( (*p) ) { case 34: goto tr24; case 92: goto st14; } goto st13; st14: if ( ++p == pe ) goto _test_eof14; case 14: goto st13; tr63: #line 1 "NONE" {te = p+1;} goto st37; st37: if ( ++p == pe ) goto _test_eof37; case 37: #line 765 "rlscan.cpp" if ( (*p) == 10 ) goto tr27; goto st15; st15: if ( ++p == pe ) goto _test_eof15; case 15: if ( (*p) == 10 ) goto tr27; goto st15; tr64: #line 1 "NONE" {te = p+1;} goto st38; st38: if ( ++p == pe ) goto _test_eof38; case 38: #line 784 "rlscan.cpp" switch( (*p) ) { case 39: goto tr29; case 92: goto st17; } goto st16; st16: if ( ++p == pe ) goto _test_eof16; case 16: switch( (*p) ) { case 39: goto tr29; case 92: goto st17; } goto st16; st17: if ( ++p == pe ) goto _test_eof17; case 17: goto st16; tr65: #line 1 "NONE" {te = p+1;} goto st39; st39: if ( ++p == pe ) goto _test_eof39; case 39: #line 812 "rlscan.cpp" switch( (*p) ) { case 47: goto tr32; case 92: goto st19; } goto st18; st18: if ( ++p == pe ) goto _test_eof18; case 18: switch( (*p) ) { case 47: goto tr32; case 92: goto st19; } goto st18; st19: if ( ++p == pe ) goto _test_eof19; case 19: goto st18; tr66: #line 1 "NONE" {te = p+1;} goto st40; st40: if ( ++p == pe ) goto _test_eof40; case 40: #line 840 "rlscan.cpp" if ( (*p) == 120 ) goto st20; if ( 48 <= (*p) && (*p) <= 57 ) goto st41; goto tr73; st41: if ( ++p == pe ) goto _test_eof41; case 41: if ( 48 <= (*p) && (*p) <= 57 ) goto st41; goto tr73; st20: if ( ++p == pe ) goto _test_eof20; case 20: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st42; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st42; } else goto st42; goto tr34; st42: if ( ++p == pe ) goto _test_eof42; case 42: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st42; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st42; } else goto st42; goto tr75; st43: if ( ++p == pe ) goto _test_eof43; case 43: if ( (*p) == 95 ) goto st43; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st43; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st43; } else goto st43; goto tr76; tr69: #line 1 "NONE" {te = p+1;} goto st44; st44: if ( ++p == pe ) goto _test_eof44; case 44: #line 902 "rlscan.cpp" switch( (*p) ) { case 92: goto st22; case 93: goto tr38; } goto st21; st21: if ( ++p == pe ) goto _test_eof21; case 21: switch( (*p) ) { case 92: goto st22; case 93: goto tr38; } goto st21; st22: if ( ++p == pe ) goto _test_eof22; case 22: goto st21; tr71: #line 1 "NONE" {te = p+1;} goto st45; st45: if ( ++p == pe ) goto _test_eof45; case 45: #line 930 "rlscan.cpp" if ( (*p) == 37 ) goto st23; goto tr72; st23: if ( ++p == pe ) goto _test_eof23; case 23: if ( (*p) == 37 ) goto tr39; goto tr22; } _test_eof24: cs = 24; goto _test_eof; _test_eof25: cs = 25; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof26: cs = 26; goto _test_eof; _test_eof27: cs = 27; goto _test_eof; _test_eof28: cs = 28; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof29: cs = 29; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof30: cs = 30; goto _test_eof; _test_eof31: cs = 31; goto _test_eof; _test_eof32: cs = 32; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof33: cs = 33; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof11: cs = 11; goto _test_eof; _test_eof34: cs = 34; goto _test_eof; _test_eof12: cs = 12; goto _test_eof; _test_eof35: cs = 35; goto _test_eof; _test_eof36: cs = 36; goto _test_eof; _test_eof13: cs = 13; goto _test_eof; _test_eof14: cs = 14; goto _test_eof; _test_eof37: cs = 37; goto _test_eof; _test_eof15: cs = 15; goto _test_eof; _test_eof38: cs = 38; goto _test_eof; _test_eof16: cs = 16; goto _test_eof; _test_eof17: cs = 17; goto _test_eof; _test_eof39: cs = 39; goto _test_eof; _test_eof18: cs = 18; goto _test_eof; _test_eof19: cs = 19; goto _test_eof; _test_eof40: cs = 40; goto _test_eof; _test_eof41: cs = 41; goto _test_eof; _test_eof20: cs = 20; goto _test_eof; _test_eof42: cs = 42; goto _test_eof; _test_eof43: cs = 43; goto _test_eof; _test_eof44: cs = 44; goto _test_eof; _test_eof21: cs = 21; goto _test_eof; _test_eof22: cs = 22; goto _test_eof; _test_eof45: cs = 45; goto _test_eof; _test_eof23: cs = 23; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 25: goto tr46; case 1: goto tr0; case 2: goto tr0; case 26: goto tr46; case 27: goto tr48; case 28: goto tr46; case 3: goto tr0; case 4: goto tr0; case 29: goto tr46; case 5: goto tr0; case 32: goto tr57; case 8: goto tr13; case 9: goto tr13; case 33: goto tr57; case 10: goto tr13; case 11: goto tr13; case 34: goto tr57; case 12: goto tr13; case 36: goto tr72; case 13: goto tr22; case 14: goto tr22; case 37: goto tr72; case 15: goto tr22; case 38: goto tr72; case 16: goto tr22; case 17: goto tr22; case 39: goto tr72; case 18: goto tr22; case 19: goto tr22; case 40: goto tr73; case 41: goto tr73; case 20: goto tr34; case 42: goto tr75; case 43: goto tr76; case 44: goto tr72; case 21: goto tr22; case 22: goto tr22; case 45: goto tr72; case 23: goto tr22; } } _out: {} } #line 282 "rlscan.rl" if ( cs == RagelScan_error ) { /* Machine failed before finding a token. */ cerr << "PARSE ERROR" << endl; exit(1); } if ( ts == 0 ) have = 0; else { /* There is a prefix to preserve, shift it over. */ have = pe - ts; memmove( inbuf, ts, have ); te = inbuf + (te-ts); ts = inbuf; } } return 0; } ragel-6.10/examples/mailbox.rl0000664000175000017500000001045313065111230013260 00000000000000/* * Parses unix mail boxes into headers and bodies. */ #include #include #include #include using namespace std; #define BUFSIZE 2048 /* A growable buffer for collecting headers. */ struct Buffer { Buffer() : data(0), allocated(0), length(0) { } ~Buffer() { empty(); } void append( char p ) { if ( ++length > allocated ) upAllocate( length*2 ); data[length-1] = p; } void clear() { length = 0; } void upAllocate( int len ); void empty(); char *data; int allocated; int length; }; struct MailboxScanner { Buffer headName; Buffer headContent; int cs, top, stack[1]; int init( ); int execute( const char *data, int len, bool isEof ); int finish( ); }; %%{ machine MailboxScanner; # Buffer the header names. action bufHeadName { headName.append(fc); } # Prints a blank line after the end of the headers of each message. action blankLine { cout << endl; } # Helpers we will use in matching the date section of the from line. day = /[A-Z][a-z][a-z]/; month = /[A-Z][a-z][a-z]/; year = /[0-9][0-9][0-9][0-9]/; time = /[0-9][0-9]:[0-9][0-9]/ . ( /:[0-9][0-9]/ | '' ); letterZone = /[A-Z][A-Z][A-Z]/; numZone = /[+\-][0-9][0-9][0-9][0-9]/; zone = letterZone | numZone; dayNum = /[0-9 ][0-9]/; # These are the different formats of the date minus an obscure # type that has a funny string 'remote from xxx' on the end. Taken # from c-client in the imap-2000 distribution. date = day . ' ' . month . ' ' . dayNum . ' ' . time . ' ' . ( year | year . ' ' . zone | zone . ' ' . year ); # From lines separate messages. We will exclude fromLine from a message # body line. This will cause us to stay in message line up until an # entirely correct from line is matched. fromLine = 'From ' . (any-'\n')* . ' ' . date . '\n'; # The types of characters that can be used as a header name. hchar = print - [ :]; # Simply eat up an uninteresting header. Return at the first non-ws # character following a newline. consumeHeader := ( [^\n] | '\n' [ \t] | '\n' [^ \t] @{fhold; fret;} )*; action hchar {headContent.append(fc);} action hspace {headContent.append(' ');} action hfinish { headContent.append(0); cout << headContent.data << endl; headContent.clear(); fhold; fret; } # Display the contents of a header as it is consumed. Collapses line # continuations to a single space. printHeader := ( [^\n] @hchar | ( '\n' ( [ \t]+ '\n' )* [ \t]+ ) %hspace )** $!hfinish; action onHeader { headName.append(0); if ( strcmp( headName.data, "From" ) == 0 || strcmp( headName.data, "To" ) == 0 || strcmp( headName.data, "Subject" ) == 0 ) { /* Print the header name, then jump to a machine the will display * the contents. */ cout << headName.data << ":"; headName.clear(); fcall printHeader; } headName.clear(); fcall consumeHeader; } header = hchar+ $bufHeadName ':' @onHeader; # Exclude fromLine from a messageLine, otherwise when encountering a # fromLine we will be simultaneously matching the old message and a new # message. messageLine = ( [^\n]* '\n' - fromLine ); # An entire message. message = ( fromLine . header* . '\n' @blankLine . messageLine* ); # File is a series of messages. main := message*; }%% %% write data; int MailboxScanner::init( ) { %% write init; return 1; } int MailboxScanner::execute( const char *data, int len, bool isEof ) { const char *p = data; const char *pe = data + len; const char *eof = isEof ? pe : 0; %% write exec; if ( cs == MailboxScanner_error ) return -1; if ( cs >= MailboxScanner_first_final ) return 1; return 0; } int MailboxScanner::finish( ) { if ( cs == MailboxScanner_error ) return -1; if ( cs >= MailboxScanner_first_final ) return 1; return 0; } void Buffer::empty() { if ( data != 0 ) { free( data ); data = 0; length = 0; allocated = 0; } } void Buffer::upAllocate( int len ) { if ( data == 0 ) data = (char*) malloc( len ); else data = (char*) realloc( data, len ); allocated = len; } MailboxScanner mailbox; char buf[BUFSIZE]; int main() { mailbox.init(); while ( 1 ) { int len = fread( buf, 1, BUFSIZE, stdin ); mailbox.execute( buf, len, len != BUFSIZE ); if ( len != BUFSIZE ) break; } if ( mailbox.finish() <= 0 ) cerr << "mailbox: error parsing input" << endl; return 0; } ragel-6.10/examples/cppscan.cpp0000664000175000017500000003771313065122770013444 00000000000000 #line 1 "cppscan.rl" /* * A C++ scanner. Uses the longest match construction. * << <= <<= >> >= >>= are left out since angle brackets are used in templates. */ #include #include #include #define TK_Dlit 256 #define TK_Slit 257 #define TK_Float 258 #define TK_Id 259 #define TK_NameSep 260 #define TK_Arrow 261 #define TK_PlusPlus 262 #define TK_MinusMinus 263 #define TK_ArrowStar 264 #define TK_DotStar 265 #define TK_ShiftLeft 266 #define TK_ShiftRight 267 #define TK_IntegerDecimal 268 #define TK_IntegerOctal 269 #define TK_IntegerHex 270 #define TK_EqualsEquals 271 #define TK_NotEquals 272 #define TK_AndAnd 273 #define TK_OrOr 274 #define TK_MultAssign 275 #define TK_DivAssign 276 #define TK_PercentAssign 277 #define TK_PlusAssign 278 #define TK_MinusAssign 279 #define TK_AmpAssign 280 #define TK_CaretAssign 281 #define TK_BarAssign 282 #define TK_DotDotDot 283 #define TK_Whitespace 284 #define TK_Comment 285 #define BUFSIZE 16384 /* EOF char used to flush out that last token. This should be a whitespace * token. */ #define LAST_CHAR 0 using std::cerr; using std::cout; using std::cin; using std::endl; static char buf[BUFSIZE]; static int line = 1, col = 1; static char *ts, *te; static int act, have = 0; static int cs; #line 63 "cppscan.cpp" static const int Scanner_start = 12; static const int Scanner_error = 0; static const int Scanner_en_c_comment = 10; static const int Scanner_en_main = 12; #line 132 "cppscan.rl" void token( int tok ) { char *data = ts; int len = te - ts; cout << '<' << tok << "> "; cout.write( data, len ); cout << '\n'; /* Count newlines and columns. This code is here mainly for having some * code in the token routine when commenting out the above output during * performance testing. */ for ( int i = 0; i < len; i ++ ) { if ( data[i] == '\n' ) { line += 1; col = 1; } else { col += 1; } } } int main() { std::ios::sync_with_stdio(false); #line 102 "cppscan.cpp" { cs = Scanner_start; ts = 0; te = 0; act = 0; } #line 162 "cppscan.rl" /* Do the first read. */ bool done = false; while ( !done ) { char *p = buf + have; int space = BUFSIZE - have; if ( space == 0 ) { /* We filled up the buffer trying to scan a token. */ cerr << "OUT OF BUFFER SPACE" << endl; exit(1); } cin.read( p, space ); int len = cin.gcount(); char *pe = p + len; char *eof = 0; /* If we see eof then append the EOF char. */ if ( cin.eof() ) { eof = pe; done = true; } #line 136 "cppscan.cpp" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr0: #line 1 "NONE" { switch( act ) { case 0: {{goto st0;}} break; case 3: {{p = ((te))-1;}token( TK_Id );} break; case 4: {{p = ((te))-1;}token( TK_Float );} break; case 5: {{p = ((te))-1;}token( TK_IntegerDecimal );} break; case 6: {{p = ((te))-1;}token( TK_IntegerOctal );} break; } } goto st12; tr2: #line 78 "cppscan.rl" {te = p+1;{token( TK_Dlit );}} goto st12; tr5: #line 76 "cppscan.rl" {te = p+1;{token( TK_Slit );}} goto st12; tr7: #line 124 "cppscan.rl" {{p = ((te))-1;}{token( ts[0] );}} goto st12; tr8: #line 121 "cppscan.rl" {te = p+1;{token( TK_DotDotDot );}} goto st12; tr12: #line 128 "cppscan.rl" {te = p+1;} goto st12; tr13: #line 90 "cppscan.rl" {{p = ((te))-1;}{token( TK_IntegerDecimal );}} goto st12; tr20: #line 124 "cppscan.rl" {te = p+1;{token( ts[0] );}} goto st12; tr36: #line 129 "cppscan.rl" {te = p;p--;} goto st12; tr37: #line 124 "cppscan.rl" {te = p;p--;{token( ts[0] );}} goto st12; tr38: #line 103 "cppscan.rl" {te = p+1;{token( TK_NotEquals );}} goto st12; tr39: #line 108 "cppscan.rl" {te = p+1;{token( TK_PercentAssign );}} goto st12; tr40: #line 104 "cppscan.rl" {te = p+1;{token( TK_AndAnd );}} goto st12; tr41: #line 111 "cppscan.rl" {te = p+1;{token( TK_AmpAssign );}} goto st12; tr42: #line 106 "cppscan.rl" {te = p+1;{token( TK_MultAssign );}} goto st12; tr43: #line 114 "cppscan.rl" {te = p+1;{token( TK_PlusPlus );}} goto st12; tr44: #line 109 "cppscan.rl" {te = p+1;{token( TK_PlusAssign );}} goto st12; tr45: #line 115 "cppscan.rl" {te = p+1;{token( TK_MinusMinus );}} goto st12; tr46: #line 110 "cppscan.rl" {te = p+1;{token( TK_MinusAssign );}} goto st12; tr48: #line 116 "cppscan.rl" {te = p;p--;{token( TK_Arrow );}} goto st12; tr49: #line 117 "cppscan.rl" {te = p+1;{token( TK_ArrowStar );}} goto st12; tr50: #line 118 "cppscan.rl" {te = p+1;{token( TK_DotStar );}} goto st12; tr53: #line 86 "cppscan.rl" {te = p;p--;{token( TK_Float );}} goto st12; tr55: #line 86 "cppscan.rl" {te = p+1;{token( TK_Float );}} goto st12; tr56: #line 127 "cppscan.rl" {te = p+1;{ {goto st10;} }} goto st12; tr57: #line 107 "cppscan.rl" {te = p+1;{token( TK_DivAssign );}} goto st12; tr58: #line 90 "cppscan.rl" {te = p;p--;{token( TK_IntegerDecimal );}} goto st12; tr62: #line 94 "cppscan.rl" {te = p;p--;{token( TK_IntegerOctal );}} goto st12; tr64: #line 94 "cppscan.rl" {te = p+1;{token( TK_IntegerOctal );}} goto st12; tr66: #line 90 "cppscan.rl" {te = p+1;{token( TK_IntegerDecimal );}} goto st12; tr67: #line 98 "cppscan.rl" {te = p;p--;{token( TK_IntegerHex );}} goto st12; tr69: #line 98 "cppscan.rl" {te = p+1;{token( TK_IntegerHex );}} goto st12; tr70: #line 101 "cppscan.rl" {te = p+1;{token( TK_NameSep );}} goto st12; tr71: #line 102 "cppscan.rl" {te = p+1;{token( TK_EqualsEquals );}} goto st12; tr72: #line 82 "cppscan.rl" {te = p;p--;{token( TK_Id );}} goto st12; tr73: #line 112 "cppscan.rl" {te = p+1;{token( TK_CaretAssign );}} goto st12; tr74: #line 113 "cppscan.rl" {te = p+1;{token( TK_BarAssign );}} goto st12; tr75: #line 105 "cppscan.rl" {te = p+1;{token( TK_OrOr );}} goto st12; st12: #line 1 "NONE" {ts = 0;} #line 1 "NONE" {act = 0;} if ( ++p == pe ) goto _test_eof12; case 12: #line 1 "NONE" {ts = p;} #line 321 "cppscan.cpp" switch( (*p) ) { case 33: goto st14; case 34: goto st1; case 37: goto st15; case 38: goto st16; case 39: goto st3; case 42: goto st17; case 43: goto st18; case 45: goto st19; case 46: goto tr26; case 47: goto tr27; case 48: goto tr28; case 58: goto st33; case 61: goto st34; case 76: goto tr33; case 94: goto st37; case 95: goto st35; case 124: goto st38; } if ( (*p) < 65 ) { if ( (*p) < 49 ) { if ( 35 <= (*p) && (*p) <= 44 ) goto tr20; } else if ( (*p) > 57 ) { if ( 59 <= (*p) && (*p) <= 64 ) goto tr20; } else goto tr29; } else if ( (*p) > 90 ) { if ( (*p) < 97 ) { if ( 91 <= (*p) && (*p) <= 96 ) goto tr20; } else if ( (*p) > 122 ) { if ( 123 <= (*p) && (*p) <= 126 ) goto tr20; } else goto st35; } else goto st35; goto st13; st13: if ( ++p == pe ) goto _test_eof13; case 13: if ( 33 <= (*p) && (*p) <= 126 ) goto tr36; goto st13; st14: if ( ++p == pe ) goto _test_eof14; case 14: if ( (*p) == 61 ) goto tr38; goto tr37; st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 10: goto tr0; case 34: goto tr2; case 92: goto st2; } goto st1; st2: if ( ++p == pe ) goto _test_eof2; case 2: goto st1; st15: if ( ++p == pe ) goto _test_eof15; case 15: if ( (*p) == 61 ) goto tr39; goto tr37; st16: if ( ++p == pe ) goto _test_eof16; case 16: switch( (*p) ) { case 38: goto tr40; case 61: goto tr41; } goto tr37; st3: if ( ++p == pe ) goto _test_eof3; case 3: switch( (*p) ) { case 10: goto tr0; case 39: goto tr5; case 92: goto st4; } goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: goto st3; st17: if ( ++p == pe ) goto _test_eof17; case 17: if ( (*p) == 61 ) goto tr42; goto tr37; st18: if ( ++p == pe ) goto _test_eof18; case 18: switch( (*p) ) { case 43: goto tr43; case 61: goto tr44; } goto tr37; st19: if ( ++p == pe ) goto _test_eof19; case 19: switch( (*p) ) { case 45: goto tr45; case 61: goto tr46; case 62: goto st20; } goto tr37; st20: if ( ++p == pe ) goto _test_eof20; case 20: if ( (*p) == 42 ) goto tr49; goto tr48; tr26: #line 1 "NONE" {te = p+1;} goto st21; st21: if ( ++p == pe ) goto _test_eof21; case 21: #line 463 "cppscan.cpp" switch( (*p) ) { case 42: goto tr50; case 46: goto st5; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr52; goto tr37; st5: if ( ++p == pe ) goto _test_eof5; case 5: if ( (*p) == 46 ) goto tr8; goto tr7; tr52: #line 1 "NONE" {te = p+1;} #line 86 "cppscan.rl" {act = 4;} goto st22; st22: if ( ++p == pe ) goto _test_eof22; case 22: #line 488 "cppscan.cpp" switch( (*p) ) { case 69: goto st6; case 70: goto tr55; case 76: goto tr55; case 101: goto st6; case 102: goto tr55; case 108: goto tr55; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr52; goto tr53; st6: if ( ++p == pe ) goto _test_eof6; case 6: switch( (*p) ) { case 43: goto st7; case 45: goto st7; } if ( 48 <= (*p) && (*p) <= 57 ) goto st23; goto tr0; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( 48 <= (*p) && (*p) <= 57 ) goto st23; goto tr0; st23: if ( ++p == pe ) goto _test_eof23; case 23: switch( (*p) ) { case 70: goto tr55; case 76: goto tr55; case 102: goto tr55; case 108: goto tr55; } if ( 48 <= (*p) && (*p) <= 57 ) goto st23; goto tr53; tr27: #line 1 "NONE" {te = p+1;} goto st24; st24: if ( ++p == pe ) goto _test_eof24; case 24: #line 539 "cppscan.cpp" switch( (*p) ) { case 42: goto tr56; case 47: goto st8; case 61: goto tr57; } goto tr37; st8: if ( ++p == pe ) goto _test_eof8; case 8: if ( (*p) == 10 ) goto tr12; goto st8; tr28: #line 1 "NONE" {te = p+1;} #line 90 "cppscan.rl" {act = 5;} goto st25; st25: if ( ++p == pe ) goto _test_eof25; case 25: #line 563 "cppscan.cpp" switch( (*p) ) { case 46: goto tr52; case 69: goto st6; case 76: goto st28; case 85: goto st28; case 101: goto st6; case 108: goto st28; case 117: goto st28; case 120: goto st9; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr59; goto tr58; tr59: #line 1 "NONE" {te = p+1;} #line 94 "cppscan.rl" {act = 6;} goto st26; st26: if ( ++p == pe ) goto _test_eof26; case 26: #line 587 "cppscan.cpp" switch( (*p) ) { case 46: goto tr52; case 69: goto st6; case 76: goto st27; case 85: goto st27; case 101: goto st6; case 108: goto st27; case 117: goto st27; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr59; goto tr62; st27: if ( ++p == pe ) goto _test_eof27; case 27: switch( (*p) ) { case 76: goto tr64; case 85: goto tr64; case 108: goto tr64; case 117: goto tr64; } goto tr62; st28: if ( ++p == pe ) goto _test_eof28; case 28: switch( (*p) ) { case 76: goto st29; case 85: goto st29; case 108: goto st29; case 117: goto st29; } goto tr58; st29: if ( ++p == pe ) goto _test_eof29; case 29: switch( (*p) ) { case 76: goto tr66; case 85: goto tr66; case 108: goto tr66; case 117: goto tr66; } goto tr58; st9: if ( ++p == pe ) goto _test_eof9; case 9: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st30; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st30; } else goto st30; goto tr13; st30: if ( ++p == pe ) goto _test_eof30; case 30: switch( (*p) ) { case 76: goto st31; case 85: goto st31; case 108: goto st31; case 117: goto st31; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st30; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st30; } else goto st30; goto tr67; st31: if ( ++p == pe ) goto _test_eof31; case 31: switch( (*p) ) { case 76: goto tr69; case 85: goto tr69; case 108: goto tr69; case 117: goto tr69; } goto tr67; tr29: #line 1 "NONE" {te = p+1;} #line 90 "cppscan.rl" {act = 5;} goto st32; st32: if ( ++p == pe ) goto _test_eof32; case 32: #line 686 "cppscan.cpp" switch( (*p) ) { case 46: goto tr52; case 69: goto st6; case 76: goto st28; case 85: goto st28; case 101: goto st6; case 108: goto st28; case 117: goto st28; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr29; goto tr58; st33: if ( ++p == pe ) goto _test_eof33; case 33: if ( (*p) == 58 ) goto tr70; goto tr37; st34: if ( ++p == pe ) goto _test_eof34; case 34: if ( (*p) == 61 ) goto tr71; goto tr37; st35: if ( ++p == pe ) goto _test_eof35; case 35: if ( (*p) == 95 ) goto st35; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st35; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st35; } else goto st35; goto tr72; tr33: #line 1 "NONE" {te = p+1;} #line 82 "cppscan.rl" {act = 3;} goto st36; st36: if ( ++p == pe ) goto _test_eof36; case 36: #line 738 "cppscan.cpp" switch( (*p) ) { case 34: goto st1; case 39: goto st3; case 95: goto st35; } if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st35; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st35; } else goto st35; goto tr72; st37: if ( ++p == pe ) goto _test_eof37; case 37: if ( (*p) == 61 ) goto tr73; goto tr37; st38: if ( ++p == pe ) goto _test_eof38; case 38: switch( (*p) ) { case 61: goto tr74; case 124: goto tr75; } goto tr37; st10: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof10; case 10: #line 775 "cppscan.cpp" if ( (*p) == 42 ) goto st11; goto st10; st11: if ( ++p == pe ) goto _test_eof11; case 11: switch( (*p) ) { case 42: goto st11; case 47: goto tr17; } goto st10; tr17: #line 70 "cppscan.rl" { {goto st12;} } goto st39; st39: if ( ++p == pe ) goto _test_eof39; case 39: #line 796 "cppscan.cpp" goto st0; st0: cs = 0; goto _out; } _test_eof12: cs = 12; goto _test_eof; _test_eof13: cs = 13; goto _test_eof; _test_eof14: cs = 14; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof15: cs = 15; goto _test_eof; _test_eof16: cs = 16; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof17: cs = 17; goto _test_eof; _test_eof18: cs = 18; goto _test_eof; _test_eof19: cs = 19; goto _test_eof; _test_eof20: cs = 20; goto _test_eof; _test_eof21: cs = 21; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof22: cs = 22; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof23: cs = 23; goto _test_eof; _test_eof24: cs = 24; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof25: cs = 25; goto _test_eof; _test_eof26: cs = 26; goto _test_eof; _test_eof27: cs = 27; goto _test_eof; _test_eof28: cs = 28; goto _test_eof; _test_eof29: cs = 29; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof30: cs = 30; goto _test_eof; _test_eof31: cs = 31; goto _test_eof; _test_eof32: cs = 32; goto _test_eof; _test_eof33: cs = 33; goto _test_eof; _test_eof34: cs = 34; goto _test_eof; _test_eof35: cs = 35; goto _test_eof; _test_eof36: cs = 36; goto _test_eof; _test_eof37: cs = 37; goto _test_eof; _test_eof38: cs = 38; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof11: cs = 11; goto _test_eof; _test_eof39: cs = 39; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 13: goto tr36; case 14: goto tr37; case 1: goto tr0; case 2: goto tr0; case 15: goto tr37; case 16: goto tr37; case 3: goto tr0; case 4: goto tr0; case 17: goto tr37; case 18: goto tr37; case 19: goto tr37; case 20: goto tr48; case 21: goto tr37; case 5: goto tr7; case 22: goto tr53; case 6: goto tr0; case 7: goto tr0; case 23: goto tr53; case 24: goto tr37; case 8: goto tr7; case 25: goto tr58; case 26: goto tr62; case 27: goto tr62; case 28: goto tr58; case 29: goto tr58; case 9: goto tr13; case 30: goto tr67; case 31: goto tr67; case 32: goto tr58; case 33: goto tr37; case 34: goto tr37; case 35: goto tr72; case 36: goto tr72; case 37: goto tr37; case 38: goto tr37; } } _out: {} } #line 187 "cppscan.rl" /* Check if we failed. */ if ( cs == Scanner_error ) { /* Machine failed before finding a token. */ cerr << "PARSE ERROR" << endl; exit(1); } /* Now set up the prefix. */ if ( ts == 0 ) have = 0; else { /* There is data that needs to be shifted over. */ have = pe - ts; memmove( buf, ts, have ); te -= (ts-buf); ts = buf; } } return 0; } ragel-6.10/examples/awkemu.rl0000664000175000017500000000432213065111230013114 00000000000000/* * Perform the basic line parsing of input performed by awk. */ #include #include #include #include %%{ machine awkemu; action start_word { ws[nwords] = fpc; } action end_word { we[nwords++] = fpc; } action start_line { nwords = 0; ls = fpc; } action end_line { printf("endline(%i): ", nwords ); fwrite( ls, 1, p - ls, stdout ); printf("\n"); for ( i = 0; i < nwords; i++ ) { printf(" word: "); fwrite( ws[i], 1, we[i] - ws[i], stdout ); printf("\n"); } } # Words in a line. word = ^[ \t\n]+; # The whitespace separating words in a line. whitespace = [ \t]; # The components in a line to break up. Either a word or a single char of # whitespace. On the word capture characters. blineElements = word >start_word %end_word | whitespace; # Star the break line elements. Just be careful to decrement the leaving # priority as we don't want multiple character identifiers to be treated as # multiple single char identifiers. line = ( blineElements** '\n' ) >start_line @end_line; # Any number of lines. main := line*; }%% %% write data noerror nofinal; #define MAXWORDS 256 #define BUFSIZE 4096 char buf[BUFSIZE]; int main() { int i, nwords = 0; char *ls = 0; char *ws[MAXWORDS]; char *we[MAXWORDS]; int cs; int have = 0; %% write init; while ( 1 ) { char *p, *pe, *data = buf + have; int len, space = BUFSIZE - have; /* fprintf( stderr, "space: %i\n", space ); */ if ( space == 0 ) { fprintf(stderr, "buffer out of space\n"); exit(1); } len = fread( data, 1, space, stdin ); /* fprintf( stderr, "len: %i\n", len ); */ if ( len == 0 ) break; /* Find the last newline by searching backwards. This is where * we will stop processing on this iteration. */ p = buf; pe = buf + have + len - 1; while ( *pe != '\n' && pe >= buf ) pe--; pe += 1; /* fprintf( stderr, "running on: %i\n", pe - p ); */ %% write exec; /* How much is still in the buffer. */ have = data + len - pe; if ( have > 0 ) memmove( buf, pe, have ); /* fprintf(stderr, "have: %i\n", have ); */ if ( len < space ) break; } if ( have > 0 ) fprintf(stderr, "input not newline terminated\n"); return 0; } ragel-6.10/examples/cppscan.rl0000664000175000017500000001054513065111230013256 00000000000000/* * A C++ scanner. Uses the longest match construction. * << <= <<= >> >= >>= are left out since angle brackets are used in templates. */ #include #include #include #define TK_Dlit 256 #define TK_Slit 257 #define TK_Float 258 #define TK_Id 259 #define TK_NameSep 260 #define TK_Arrow 261 #define TK_PlusPlus 262 #define TK_MinusMinus 263 #define TK_ArrowStar 264 #define TK_DotStar 265 #define TK_ShiftLeft 266 #define TK_ShiftRight 267 #define TK_IntegerDecimal 268 #define TK_IntegerOctal 269 #define TK_IntegerHex 270 #define TK_EqualsEquals 271 #define TK_NotEquals 272 #define TK_AndAnd 273 #define TK_OrOr 274 #define TK_MultAssign 275 #define TK_DivAssign 276 #define TK_PercentAssign 277 #define TK_PlusAssign 278 #define TK_MinusAssign 279 #define TK_AmpAssign 280 #define TK_CaretAssign 281 #define TK_BarAssign 282 #define TK_DotDotDot 283 #define TK_Whitespace 284 #define TK_Comment 285 #define BUFSIZE 16384 /* EOF char used to flush out that last token. This should be a whitespace * token. */ #define LAST_CHAR 0 using std::cerr; using std::cout; using std::cin; using std::endl; static char buf[BUFSIZE]; static int line = 1, col = 1; static char *ts, *te; static int act, have = 0; static int cs; %%{ machine Scanner; write data nofinal; # Floating literals. fract_const = digit* '.' digit+ | digit+ '.'; exponent = [eE] [+\-]? digit+; float_suffix = [flFL]; c_comment := any* :>> '*/' @{ fgoto main; }; main := |* # Single and double literals. ( 'L'? "'" ( [^'\\\n] | /\\./ )* "'" ) {token( TK_Slit );}; ( 'L'? '"' ( [^"\\\n] | /\\./ )* '"' ) {token( TK_Dlit );}; # Identifiers ( [a-zA-Z_] [a-zA-Z0-9_]* ) {token( TK_Id );}; # Floating literals. ( fract_const exponent? float_suffix? | digit+ exponent float_suffix? ) {token( TK_Float );}; # Integer decimal. Leading part buffered by float. ( ( '0' | [1-9] [0-9]* ) [ulUL]{0,3} ) {token( TK_IntegerDecimal );}; # Integer octal. Leading part buffered by float. ( '0' [0-9]+ [ulUL]{0,2} ) {token( TK_IntegerOctal );}; # Integer hex. Leading 0 buffered by float. ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]{0,2} ) ) {token( TK_IntegerHex );}; # Only buffer the second item, first buffered by symbol. */ '::' {token( TK_NameSep );}; '==' {token( TK_EqualsEquals );}; '!=' {token( TK_NotEquals );}; '&&' {token( TK_AndAnd );}; '||' {token( TK_OrOr );}; '*=' {token( TK_MultAssign );}; '/=' {token( TK_DivAssign );}; '%=' {token( TK_PercentAssign );}; '+=' {token( TK_PlusAssign );}; '-=' {token( TK_MinusAssign );}; '&=' {token( TK_AmpAssign );}; '^=' {token( TK_CaretAssign );}; '|=' {token( TK_BarAssign );}; '++' {token( TK_PlusPlus );}; '--' {token( TK_MinusMinus );}; '->' {token( TK_Arrow );}; '->*' {token( TK_ArrowStar );}; '.*' {token( TK_DotStar );}; # Three char compounds, first item already buffered. */ '...' {token( TK_DotDotDot );}; # Single char symbols. ( punct - [_"'] ) {token( ts[0] );}; # Comments and whitespace. '/*' { fgoto c_comment; }; '//' [^\n]* '\n'; ( any - 33..126 )+; *|; }%% void token( int tok ) { char *data = ts; int len = te - ts; cout << '<' << tok << "> "; cout.write( data, len ); cout << '\n'; /* Count newlines and columns. This code is here mainly for having some * code in the token routine when commenting out the above output during * performance testing. */ for ( int i = 0; i < len; i ++ ) { if ( data[i] == '\n' ) { line += 1; col = 1; } else { col += 1; } } } int main() { std::ios::sync_with_stdio(false); %% write init; /* Do the first read. */ bool done = false; while ( !done ) { char *p = buf + have; int space = BUFSIZE - have; if ( space == 0 ) { /* We filled up the buffer trying to scan a token. */ cerr << "OUT OF BUFFER SPACE" << endl; exit(1); } cin.read( p, space ); int len = cin.gcount(); char *pe = p + len; char *eof = 0; /* If we see eof then append the EOF char. */ if ( cin.eof() ) { eof = pe; done = true; } %% write exec; /* Check if we failed. */ if ( cs == Scanner_error ) { /* Machine failed before finding a token. */ cerr << "PARSE ERROR" << endl; exit(1); } /* Now set up the prefix. */ if ( ts == 0 ) have = 0; else { /* There is data that needs to be shifted over. */ have = pe - ts; memmove( buf, ts, have ); te -= (ts-buf); ts = buf; } } return 0; } ragel-6.10/examples/clang.c0000664000175000017500000001650513065122770012535 00000000000000 #line 1 "clang.rl" /* * A mini C-like language scanner. */ #include #include #include #line 91 "clang.rl" #line 17 "clang.c" static const int clang_start = 10; static const int clang_error = 0; static const int clang_en_c_comment = 8; static const int clang_en_main = 10; #line 94 "clang.rl" #define BUFSIZE 128 void scanner() { static char buf[BUFSIZE]; int cs, act, have = 0, curline = 1; char *ts, *te = 0; int done = 0; #line 37 "clang.c" { cs = clang_start; ts = 0; te = 0; act = 0; } #line 105 "clang.rl" while ( !done ) { char *p = buf + have, *pe, *eof = 0; int len, space = BUFSIZE - have; if ( space == 0 ) { /* We've used up the entire buffer storing an already-parsed token * prefix that must be preserved. */ fprintf(stderr, "OUT OF BUFFER SPACE\n" ); exit(1); } len = fread( p, 1, space, stdin ); pe = p + len; /* Check if this is the end of file. */ if ( len < space ) { eof = pe; done = 1; } #line 68 "clang.c" { if ( p == pe ) goto _test_eof; switch ( cs ) { tr2: #line 50 "clang.rl" {te = p+1;{ printf( "double_lit(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; tr6: #line 42 "clang.rl" {te = p+1;{ printf( "single_lit(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; tr8: #line 28 "clang.rl" {{p = ((te))-1;}{ printf( "symbol(%i): %c\n", curline, ts[0] ); }} goto st10; tr10: #line 12 "clang.rl" {curline += 1;} #line 62 "clang.rl" {te = p+1;} goto st10; tr11: #line 68 "clang.rl" {{p = ((te))-1;}{ printf( "int(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; tr18: #line 57 "clang.rl" {te = p+1;} goto st10; tr19: #line 12 "clang.rl" {curline += 1;} #line 57 "clang.rl" {te = p+1;} goto st10; tr20: #line 28 "clang.rl" {te = p+1;{ printf( "symbol(%i): %c\n", curline, ts[0] ); }} goto st10; tr25: #line 28 "clang.rl" {te = p;p--;{ printf( "symbol(%i): %c\n", curline, ts[0] ); }} goto st10; tr26: #line 64 "clang.rl" {te = p+1;{ {goto st8;} }} goto st10; tr27: #line 68 "clang.rl" {te = p;p--;{ printf( "int(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; tr30: #line 76 "clang.rl" {te = p;p--;{ printf( "float(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; tr31: #line 84 "clang.rl" {te = p;p--;{ printf( "hex(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; tr32: #line 34 "clang.rl" {te = p;p--;{ printf( "ident(%i): ", curline ); fwrite( ts, 1, te-ts, stdout ); printf("\n"); }} goto st10; st10: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof10; case 10: #line 1 "NONE" {ts = p;} #line 176 "clang.c" switch( (*p) ) { case 10: goto tr19; case 34: goto st1; case 39: goto st3; case 47: goto tr21; case 48: goto tr22; case 95: goto st16; } if ( (*p) < 65 ) { if ( (*p) < 49 ) { if ( 33 <= (*p) && (*p) <= 46 ) goto tr20; } else if ( (*p) > 57 ) { if ( 58 <= (*p) && (*p) <= 64 ) goto tr20; } else goto tr23; } else if ( (*p) > 90 ) { if ( (*p) < 97 ) { if ( 91 <= (*p) && (*p) <= 96 ) goto tr20; } else if ( (*p) > 122 ) { if ( 123 <= (*p) && (*p) <= 126 ) goto tr20; } else goto st16; } else goto st16; goto tr18; tr1: #line 12 "clang.rl" {curline += 1;} goto st1; st1: if ( ++p == pe ) goto _test_eof1; case 1: #line 214 "clang.c" switch( (*p) ) { case 10: goto tr1; case 34: goto tr2; case 92: goto st2; } goto st1; st2: if ( ++p == pe ) goto _test_eof2; case 2: if ( (*p) == 10 ) goto tr1; goto st1; tr5: #line 12 "clang.rl" {curline += 1;} goto st3; st3: if ( ++p == pe ) goto _test_eof3; case 3: #line 236 "clang.c" switch( (*p) ) { case 10: goto tr5; case 39: goto tr6; case 92: goto st4; } goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: if ( (*p) == 10 ) goto tr5; goto st3; tr21: #line 1 "NONE" {te = p+1;} goto st11; st11: if ( ++p == pe ) goto _test_eof11; case 11: #line 258 "clang.c" switch( (*p) ) { case 42: goto tr26; case 47: goto st5; } goto tr25; st5: if ( ++p == pe ) goto _test_eof5; case 5: if ( (*p) == 10 ) goto tr10; goto st5; tr22: #line 1 "NONE" {te = p+1;} goto st12; st12: if ( ++p == pe ) goto _test_eof12; case 12: #line 279 "clang.c" switch( (*p) ) { case 46: goto st6; case 120: goto st7; } if ( 48 <= (*p) && (*p) <= 57 ) goto tr23; goto tr27; st6: if ( ++p == pe ) goto _test_eof6; case 6: if ( 48 <= (*p) && (*p) <= 57 ) goto st13; goto tr11; st13: if ( ++p == pe ) goto _test_eof13; case 13: if ( 48 <= (*p) && (*p) <= 57 ) goto st13; goto tr30; tr23: #line 1 "NONE" {te = p+1;} goto st14; st14: if ( ++p == pe ) goto _test_eof14; case 14: #line 309 "clang.c" if ( (*p) == 46 ) goto st6; if ( 48 <= (*p) && (*p) <= 57 ) goto tr23; goto tr27; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st15; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st15; } else goto st15; goto tr11; st15: if ( ++p == pe ) goto _test_eof15; case 15: if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st15; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) goto st15; } else goto st15; goto tr31; st16: if ( ++p == pe ) goto _test_eof16; case 16: if ( (*p) == 95 ) goto st16; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st16; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) goto st16; } else goto st16; goto tr32; tr15: #line 12 "clang.rl" {curline += 1;} goto st8; st8: #line 1 "NONE" {ts = 0;} if ( ++p == pe ) goto _test_eof8; case 8: #line 366 "clang.c" switch( (*p) ) { case 10: goto tr15; case 42: goto st9; } goto st8; st9: if ( ++p == pe ) goto _test_eof9; case 9: switch( (*p) ) { case 10: goto tr15; case 42: goto st9; case 47: goto tr17; } goto st8; tr17: #line 16 "clang.rl" {{goto st10;}} goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: #line 390 "clang.c" goto st0; st0: cs = 0; goto _out; } _test_eof10: cs = 10; goto _test_eof; _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof11: cs = 11; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof12: cs = 12; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof13: cs = 13; goto _test_eof; _test_eof14: cs = 14; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof15: cs = 15; goto _test_eof; _test_eof16: cs = 16; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof17: cs = 17; goto _test_eof; _test_eof: {} if ( p == eof ) { switch ( cs ) { case 11: goto tr25; case 5: goto tr8; case 12: goto tr27; case 6: goto tr11; case 13: goto tr30; case 14: goto tr27; case 7: goto tr11; case 15: goto tr31; case 16: goto tr32; } } _out: {} } #line 127 "clang.rl" if ( cs == clang_error ) { fprintf(stderr, "PARSE ERROR\n" ); break; } if ( ts == 0 ) have = 0; else { /* There is a prefix to preserve, shift it over. */ have = pe - ts; memmove( buf, ts, have ); te = buf + (te-ts); ts = buf; } } } int main() { scanner(); return 0; }