Improvements to the handling of write statements in the backend.
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Thu, 1 Feb 2007 20:41:15 +0000 (20:41 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Thu, 1 Feb 2007 20:41:15 +0000 (20:41 +0000)
git-svn-id: http://svn.complang.org/ragel/trunk@48 052ea7fc-9027-0410-9066-f65837a77df0

ragel/ragel.h
ragel/rlscan.rl
rlcodegen/fsmcodegen.cpp
rlcodegen/fsmcodegen.h
rlcodegen/gendata.cpp
rlcodegen/gendata.h
rlcodegen/splitcodegen.cpp
rlcodegen/xmlparse.kh
rlcodegen/xmlparse.kl
rlcodegen/xmlscan.rl
rlcodegen/xmltags.gperf

index 23c8d29..d070217 100644 (file)
@@ -73,8 +73,4 @@ void checkMachines( );
 void writeMachines( std::ostream &out, std::string hostData, char *inputFileName );
 void xmlEscapeHost( std::ostream &out, char *data, int len );
 
-
-/* Size of the include stack. */
-#define INCLUDE_STACK_SIZE 32
-
 #endif /* _RAGEL_H */
index 004f4d0..c765891 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2006 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2006-2007 Adrian Thurston <thurston@cs.queensu.ca>
  */
 
 /*  This file is part of Ragel.
@@ -294,27 +294,21 @@ void Scanner::token( int type )
 
        action write_command
        {
-               if ( active ) {
-                       if ( strcmp( tokdata, "data" ) != 0 &&
-                                       strcmp( tokdata, "init" ) != 0 &&
-                                       strcmp( tokdata, "exec" ) != 0 &&
-                                       strcmp( tokdata, "eof" ) != 0 )
-                       {
-                               scan_error() << "unknown write command" << endl;
-                       }
-
-                       if ( machineSpec == 0 && machineName == 0 ) {
-                               output << "<write def_name=\"" << parser->sectionName << 
-                                               "\" what=\"" << tokdata << "\">";
-                       }
+               if ( active && machineSpec == 0 && machineName == 0 ) {
+                       output << "<write"
+                                       " def_name=\"" << parser->sectionName << "\""
+                                       " line=\"" << line << "\""
+                                       " col=\"" << column << "\""
+                                       ">";
                }
        }
 
-       action write_option
+       action write_arg
        {
-               if ( active )
-                       output << "<option>" << tokdata << "</option>";
+               if ( active && machineSpec == 0 && machineName == 0 )
+                       output << "<arg>" << tokdata << "</arg>";
        }
+
        action write_close
        {
                if ( active && machineSpec == 0 && machineName == 0 )
@@ -322,8 +316,8 @@ void Scanner::token( int type )
        }
 
        write_stmt =
-               ( KW_Write TK_Word @write_command 
-                       ( TK_Word @write_option )* ';' @write_close )
+               ( KW_Write @write_command 
+               ( TK_Word @write_arg )+ ';' @write_close )
                <>err write_err <>eof write_err;
 
        action handle_token
index 39c2623..9aea722 100644 (file)
@@ -46,7 +46,8 @@ using std::string;
 using std::cerr;
 using std::endl;
 
-CodeGenData *makeCodeGen( char *fileName, char *fsmName, ostream &out, bool wantComplete )
+CodeGenData *makeCodeGen( char *sourceFileName, char *fsmName, 
+               ostream &out, bool wantComplete )
 {
        FsmCodeGen *codeGen = 0;
        switch ( hostLangType ) {
@@ -120,7 +121,7 @@ CodeGenData *makeCodeGen( char *fileName, char *fsmName, ostream &out, bool want
                break;
        }
 
-       codeGen->fileName = fileName;
+       codeGen->sourceFileName = sourceFileName;
        codeGen->fsmName = fsmName;
        codeGen->wantComplete = wantComplete;
 
@@ -482,7 +483,7 @@ string FsmCodeGen::LDIR_PATH( char *path )
 void FsmCodeGen::ACTION( ostream &ret, Action *action, int targState, bool inFinish )
 {
        /* Write the preprocessor line info for going into the source file. */
-       lineDirective( ret, fileName, action->loc.line );
+       lineDirective( ret, sourceFileName, action->loc.line );
 
        /* Write the block and close it off. */
        ret << "\t{";
@@ -493,7 +494,7 @@ void FsmCodeGen::ACTION( ostream &ret, Action *action, int targState, bool inFin
 void FsmCodeGen::CONDITION( ostream &ret, Action *condition )
 {
        ret << "\n";
-       lineDirective( ret, fileName, condition->loc.line );
+       lineDirective( ret, sourceFileName, condition->loc.line );
        INLINE_LIST( ret, condition->inlineList, 0, false );
 }
 
@@ -873,42 +874,55 @@ void FsmCodeGen::finishRagelDef()
        }
 }
 
-void FsmCodeGen::writeStatement( char *what, int nopts, char **options )
+void FsmCodeGen::writeStatement( InputLoc &loc, int nargs, char **args )
 {
-       /* Read the options. FIXME: These should be parsed according to each
-        * particualr function below. */
-       for ( int i = 0; i < nopts; i++ ) {
-               if ( strcmp( options[i], "noend" ) == 0 )
-                       hasEnd = false;
-               else if ( strcmp( options[i], "noerror" ) == 0 )
-                       writeErr = false;
-               else if ( strcmp( options[i], "noprefix" ) == 0 )
-                       dataPrefix = false;
-               else if ( strcmp( options[i], "nofinal" ) == 0 )
-                       writeFirstFinal = false;
-               else {
-                       //warning($1->loc) << "unrecognized write option" << endl;
-               }
-       }
-
        if ( outputFormat == OutCode ) {
                /* Force a newline. */
                out << "\n";
                genLineDirective( out );
 
-               if ( strcmp( what, "data" ) == 0 ) {
+               if ( strcmp( args[0], "data" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               if ( strcmp( args[i], "noerror" ) == 0 )
+                                       writeErr = false;
+                               else if ( strcmp( args[i], "noprefix" ) == 0 )
+                                       dataPrefix = false;
+                               else if ( strcmp( args[i], "nofinal" ) == 0 )
+                                       writeFirstFinal = false;
+                               else {
+                                       source_warning(loc) << "unrecognized write option \"" << 
+                                                       args[i] << "\"" << endl;
+                               }
+                       }
                        writeOutData();
                }
-               else if ( strcmp( what, "init" ) == 0 ) {
+               else if ( strcmp( args[0], "init" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               source_warning(loc) << "unrecognized write option \"" << 
+                                               args[i] << "\"" << endl;
+                       }
                        writeOutInit();
                }
-               else if ( strcmp( what, "exec" ) == 0 ) {
+               else if ( strcmp( args[0], "exec" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               if ( strcmp( args[i], "noend" ) == 0 )
+                                       hasEnd = false;
+                               else {
+                                       source_warning(loc) << "unrecognized write option \"" << 
+                                                       args[i] << "\"" << endl;
+                               }
+                       }
+
                        /* Must set labels immediately before writing because we may depend
                         * on the noend write option. */
                        setLabelsNeeded();
                        writeOutExec();
                }
-               else if ( strcmp( what, "eof" ) == 0 ) {
+               else if ( strcmp( args[0], "eof" ) == 0 ) {
+                       for ( int i = 1; i < nargs; i++ ) {
+                               source_warning(loc) << "unrecognized write option \"" << 
+                                               args[i] << "\"" << endl;
+                       }
                        writeOutEOF();
                }
                else {
index efb794d..ab4b4da 100644 (file)
@@ -180,7 +180,7 @@ public:
        void prepareMachine();
 
        virtual void finishRagelDef();
-       void writeStatement( char *what, int nopts, char **options );
+       virtual void writeStatement( InputLoc &loc, int nargs, char **args );
 
        /* Determine if we should use indicies. */
        virtual void calcIndexSize() {}
index 7fa38f1..b2adb57 100644 (file)
@@ -29,7 +29,7 @@ using std::endl;
 
 CodeGenData::CodeGenData( ostream &out )
 :
-       fileName(0),
+       sourceFileName(0),
        fsmName(0), 
        out(out),
        redFsm(0), 
@@ -616,6 +616,21 @@ void CodeGenData::analyzeMachine()
        setValueLimits();
 }
 
+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;
+}
+
+
 
 void lineDirective( ostream &out, char *fileName, int line )
 {
index 8418a8e..7945c18 100644 (file)
@@ -48,7 +48,7 @@ struct CodeGenData
         * Collecting the machine.
         */
 
-       char *fileName;
+       char *sourceFileName;
        char *fsmName;
        ostream &out;
        RedFsmAp *redFsm;
@@ -122,14 +122,18 @@ struct CodeGenData
        void prepareMachine();
        bool hasBeenPrepared;
 
+       ostream &source_warning(const InputLoc &loc);
+       ostream &source_error(const InputLoc &loc);
+
        /* The interface to the code generator. */
        virtual void finishRagelDef() {}
-       virtual void writeStatement( char *what, int nopts, char **options ) {}
+       virtual void writeStatement( InputLoc &loc, int nargs, char **args ) {}
 };
 
 void lineDirective( ostream &out, char *fileName, int line );
 void genLineDirective( ostream &out );
 
-CodeGenData *makeCodeGen( char *fileName, char *fsmName, ostream &out, bool wantComplete );
+CodeGenData *makeCodeGen( char *sourceFileName, 
+               char *fsmName, ostream &out, bool wantComplete );
 
 #endif /* _GENDATA_H */
index 305be6b..5b3a836 100644 (file)
@@ -341,8 +341,8 @@ std::ostream &SplitCodeGen::ALL_PARTITIONS()
        for ( int p = 0; p < redFsm->nParts; p++ ) {
                char suffix[10];
                sprintf( suffix, suffFormat, p );
-               char *fn = fileNameFromStem( fileName, suffix );
-               char *include = fileNameFromStem( fileName, ".h" );
+               char *fn = fileNameFromStem( sourceFileName, suffix );
+               char *include = fileNameFromStem( sourceFileName, ".h" );
 
                /* Create the filter on the output and open it. */
                output_filter *partFilter = new output_filter( fn );
index ffaf8f8..b119864 100644 (file)
@@ -69,7 +69,7 @@ struct Parser
                        TAG_entry, TAG_data, TAG_lm_switch, TAG_init_act, TAG_set_act,
                        TAG_set_tokend, TAG_get_tokend, TAG_init_tokstart,
                        TAG_set_tokstart, TAG_write, TAG_curstate, TAG_access, TAG_break,
-                       TAG_option;
+                       TAG_arg;
        }%%
 
        %% write instance_data;
index 5ae28a0..d1d463f 100644 (file)
@@ -135,7 +135,8 @@ tag_ragel_def_head: TAG_ragel_def
                        }
                }
                else {
-                       cgd = makeCodeGen( sourceFileName, fsmName, *outStream, wantComplete );
+                       cgd = makeCodeGen( sourceFileName, fsmName, 
+                                       *outStream, wantComplete );
                }
 
                ::keyOps = &cgd->thisKeyOps;
@@ -173,51 +174,53 @@ tag_curstate_expr: TAG_curstate inline_list '/' TAG_curstate
 
 tag_write: tag_write_head write_option_list '/' TAG_write
        final {
-               Attribute *what = $1->tag->findAttr( "what" );
-               if ( what == 0 ) {
-                       error($1->loc) << "tag <write> requires a what attribute" << endl;
-               }
-               else {
-                       writeOptions.append(0);
-                       cgd->writeStatement( what->value, writeOptions.length()-1, writeOptions.data );
-                       writeOptions.empty();
-               }
+               writeOptions.append(0);
+               cgd->writeStatement( $1->loc, writeOptions.length()-1, writeOptions.data );
+               writeOptions.empty();
        };
 
 nonterm tag_write_head
 {
-       XMLTag *tag;
        InputLoc loc;
 };
 
 tag_write_head: TAG_write
        final {
                Attribute *nameAttr = $1->tag->findAttr( "def_name" );
-               if ( nameAttr == 0 ) {
+               Attribute *lineAttr = $1->tag->findAttr( "line" );
+               Attribute *colAttr = $1->tag->findAttr( "col" );
+
+               if ( nameAttr == 0 )
                        error($1->loc) << "tag <write> requires a def_name attribute" << endl;
-               }
-               else {
-                       CodeGenMapEl *mapEl = codeGenMap.find( nameAttr->value );
-                       assert( mapEl != 0 );
-                       cgd = mapEl->value;
-               }
+               if ( lineAttr == 0 )
+                       error($1->loc) << "tag <write> requires a line attribute" << endl;
+               if ( colAttr == 0 )
+                       error($1->loc) << "tag <write> requires a col attribute" << endl;
 
-               ::keyOps = &cgd->thisKeyOps;
+               if ( nameAttr != 0 && lineAttr != 0 && colAttr != 0 ) {
+                       CodeGenMapEl *mapEl = codeGenMap.find( nameAttr->value );
+                       if ( mapEl == 0 )
+                               error($1->loc) << "internal error: cannot find codeGen" << endl;
+                       else {
+                               cgd = mapEl->value;
+                               ::keyOps = &cgd->thisKeyOps;
+                       }
 
-               $$->tag = $1->tag;
-               $$->loc = $1->loc;
+                       $$->loc.line = atoi(lineAttr->value);
+                       $$->loc.col = atoi(colAttr->value);
+               }
        };
 
 
-write_option_list: write_option_list tag_option;
+write_option_list: write_option_list tag_arg;
 write_option_list: ;
 
-nonterm tag_option
+nonterm tag_arg
 {
        char *option;
 };
 
-tag_option: TAG_option '/' TAG_option
+tag_arg: TAG_arg '/' TAG_arg
        final {
                writeOptions.append( $3->tag->content );
        };
index 7df9d46..bf52eb3 100644 (file)
@@ -308,7 +308,7 @@ int xml_parse( std::istream &input, char *fileName,
                                /* Get content for closing tags. */
                                if ( token == TK_CloseTag ) {
                                        switch ( tagId->id ) {
-                                       case TAG_host: case TAG_option:
+                                       case TAG_host: case TAG_arg:
                                        case TAG_t: case TAG_alphtype:
                                        case TAG_text: case TAG_goto:
                                        case TAG_call: case TAG_next:
index 2554e24..31c32d1 100644 (file)
@@ -74,7 +74,7 @@ write, TAG_write
 curstate, TAG_curstate
 access, TAG_access
 break, TAG_break
-option, TAG_option
+arg, TAG_arg
 cond_space_list, TAG_cond_space_list
 cond_space, TAG_cond_space
 cond_list, TAG_cond_list