Parse errors in the intermediate XML file now cause the backend to exit
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Sun, 29 Apr 2007 16:03:30 +0000 (16:03 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Sun, 29 Apr 2007 16:03:30 +0000 (16:03 +0000)
immediately. The recovery infrastructure isn't there and segfaults are likely.

When no input is given to the backend program, it should not print an error
message, it should just return a non-zero exit status. The assumption is that
the frontend printed an error.

All backend error functions now use gblErrorCount.

git-svn-id: http://svn.complang.org/ragel/trunk@209 052ea7fc-9027-0410-9066-f65837a77df0

12 files changed:
common/common.cpp
common/common.h
ragel/parsedata.cpp
ragel/parsedata.h
redfsm/gendata.cpp
redfsm/gendata.h
redfsm/xmlparse.kl
redfsm/xmlscan.rl
rlgen-cd/main.cpp
rlgen-dot/main.cpp
rlgen-java/main.cpp
rlgen-ruby/main.cpp

index 8a39727..63d8e72 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "pcheck.h"
 #include "common.h"
+#include "stdlib.h"
 #include <assert.h>
 
 HostType hostTypesC[] =
@@ -271,4 +272,10 @@ char *fileNameFromStem( char *stemFile, char *suffix )
        return retVal;
 }
 
+exit_object endp;
 
+void operator<<( std::ostream &out, exit_object & )
+{
+    out << std::endl;
+    exit(1);
+}
index 6c6720b..864c3ff 100644 (file)
@@ -305,4 +305,8 @@ struct Export
 
 typedef DList<Export> ExportList;
 
+struct exit_object { };
+extern exit_object endp;
+void operator<<( std::ostream &out, exit_object & );
+
 #endif /* _COMMON_H */
index 206ad50..2852134 100644 (file)
@@ -441,7 +441,6 @@ ParseData::ParseData( char *fileName, char *sectionName,
        fileName(fileName),
        sectionName(sectionName),
        sectionLoc(sectionLoc),
-       errorCount(0),
        curActionOrd(0),
        curPriorOrd(0),
        rootName(0),
index 2d614ae..0def9ad 100644 (file)
@@ -279,9 +279,6 @@ struct ParseData
        char *sectionName;
        InputLoc sectionLoc;
 
-       /* Number of errors encountered parsing the fsm spec. */
-       int errorCount;
-
        /* Counting the action and priority ordering. */
        int curActionOrd;
        int curPriorOrd;
index a5ff123..b197f76 100644 (file)
@@ -25,6 +25,9 @@
 using std::cerr;
 using std::endl;
 
+/* Total error count. */
+int gblErrorCount = 0;
+
 CodeGenData::CodeGenData( ostream &out )
 :
        sourceFileName(0),
@@ -51,7 +54,6 @@ CodeGenData::CodeGenData( ostream &out )
        tokendExpr(0),
        wantComplete(0),
        hasLongestMatch(false),
-       codeGenErrCount(0),
        hasEnd(true),
        dataPrefix(true),
        writeFirstFinal(true),
@@ -720,7 +722,7 @@ ostream &CodeGenData::source_warning( const InputLoc &loc )
 
 ostream &CodeGenData::source_error( const InputLoc &loc )
 {
-       codeGenErrCount += 1;
+       gblErrorCount += 1;
        assert( sourceFileName != 0 );
        cerr << sourceFileName << ":" << loc.line << ":" << loc.col << ": ";
        return cerr;
index 34d9bec..ee450a2 100644 (file)
@@ -34,6 +34,8 @@ typedef DList<Action> ActionList;
 
 typedef unsigned long ulong;
 
+extern int gblErrorCount;
+
 struct CodeGenData;
 
 typedef AvlMap<char *, CodeGenData*, CmpStr> CodeGenMap;
@@ -115,7 +117,6 @@ struct CodeGenData
        EntryIdVect entryPointIds;
        EntryNameVect entryPointNames;
        bool hasLongestMatch;
-       int codeGenErrCount;
        ExportList exportList;
 
        /* Write options. */
index 5a969b9..5846f3b 100644 (file)
@@ -45,8 +45,9 @@ start: tag_ragel;
 start:
        final {
                /* If we get no input the assumption is that the frontend died and
-                * emitted an error. */ 
-               errCount += 1;
+                * emitted an error. This forces the backend to return a non-zero
+                * exit status, but does not print an error. */
+               gblErrorCount += 1;
        };
 
 tag_ragel: tag_ragel_head ragel_def_list host_or_write_list '/' TAG_ragel;
@@ -54,16 +55,14 @@ tag_ragel: tag_ragel_head ragel_def_list host_or_write_list '/' TAG_ragel;
 tag_ragel_head: TAG_ragel
        final {
                Attribute *fileNameAttr = $1->tag->findAttr( "filename" );
-               if ( fileNameAttr == 0 ) {
-                       error($1->loc) << "tag <ragel> requires a filename attribute" << endl;
-                       exit(1);
-               }
+               if ( fileNameAttr == 0 )
+                       error($1->loc) << "tag <ragel> requires a filename attribute" << endp;
                else {
                        sourceFileName = fileNameAttr->value;
 
                        Attribute *langAttr = $1->tag->findAttr( "lang" );
                        if ( langAttr == 0 )
-                               error($1->loc) << "tag <ragel> requires a lang attribute" << endl;
+                               error($1->loc) << "tag <ragel> requires a lang attribute" << endp;
                        else {
                                if ( strcmp( langAttr->value, "C" ) == 0 ) {
                                        hostLangType = CCode;
@@ -83,7 +82,7 @@ tag_ragel_head: TAG_ragel
                                }
                                else {
                                        error($1->loc) << "expecting lang attribute to be "
-                                                       "one of C, D, Java or Ruby" << endl;
+                                                       "one of C, D, Java or Ruby" << endp;
                                }
 
                                outStream = openOutput( sourceFileName );
@@ -105,7 +104,7 @@ tag_host:
        final {
                Attribute *lineAttr = $1->tag->findAttr( "line" );
                if ( lineAttr == 0 )
-                       error($1->loc) << "tag <host> requires a line attribute" << endl;
+                       error($1->loc) << "tag <host> requires a line attribute" << endp;
                else {
                        int line = atoi( lineAttr->value );
                        if ( outputActive )
@@ -181,7 +180,7 @@ tag_export: TAG_ex '/' TAG_ex
        final {
                Attribute *nameAttr = $1->tag->findAttr( "name" );
                if ( nameAttr == 0 )
-                       error($1->loc) << "tag <ex> requires a name attribute" << endl;
+                       error($1->loc) << "tag <ex> requires a name attribute" << endp;
                else {
                        char *td = $3->tag->content;
                        Key exportKey = readKey( td, &td );
@@ -192,7 +191,7 @@ tag_export: TAG_ex '/' TAG_ex
 tag_alph_type: TAG_alphtype '/' TAG_alphtype
        final {
                if ( ! cgd->setAlphType( $3->tag->content ) )
-                       error($1->loc) << "tag <alphtype> specifies unknown alphabet type" << endl;
+                       error($1->loc) << "tag <alphtype> specifies unknown alphabet type" << endp;
        };
 
 tag_getkey_expr: TAG_getkey inline_list '/' TAG_getkey
@@ -229,9 +228,6 @@ tag_write: tag_write_head write_option_list '/' TAG_write
                writeOptions.append(0);
                cgd->writeStatement( $1->loc, writeOptions.length()-1, writeOptions.data );
 
-               /* CodeGenData may have issued an error. */
-               errCount += cgd->codeGenErrCount;
-
                /* Clear the options in prep for the next write statement. */
                writeOptions.empty();
        };
@@ -248,16 +244,16 @@ tag_write_head: TAG_write
                Attribute *colAttr = $1->tag->findAttr( "col" );
 
                if ( nameAttr == 0 )
-                       error($1->loc) << "tag <write> requires a def_name attribute" << endl;
+                       error($1->loc) << "tag <write> requires a def_name attribute" << endp;
                if ( lineAttr == 0 )
-                       error($1->loc) << "tag <write> requires a line attribute" << endl;
+                       error($1->loc) << "tag <write> requires a line attribute" << endp;
                if ( colAttr == 0 )
-                       error($1->loc) << "tag <write> requires a col attribute" << endl;
+                       error($1->loc) << "tag <write> requires a col attribute" << endp;
 
                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;
+                               error($1->loc) << "internal error: cannot find codeGen" << endp;
                        else {
                                cgd = mapEl->value;
                                ::keyOps = &cgd->thisKeyOps;
@@ -334,7 +330,7 @@ tag_entry: TAG_entry '/' TAG_entry
                Attribute *nameAttr = $1->tag->findAttr( "name" );
                if ( nameAttr == 0 ) {
                        error($1->loc) << "tag <entry_points>::<entry> "
-                                       "requires a name attribute" << endl;
+                                       "requires a name attribute" << endp;
                }
                else {
                        char *data = $3->tag->content;
@@ -349,7 +345,7 @@ tag_state_list_head: TAG_state_list
        final {
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 )
-                       error($1->loc) << "tag <state_list> requires a length attribute" << endl;
+                       error($1->loc) << "tag <state_list> requires a length attribute" << endp;
                else {
                        unsigned long length = strtoul( lengthAttr->value, 0, 10 );
                        cgd->initStateList( length );
@@ -364,7 +360,7 @@ tag_state: TAG_state state_item_list '/' TAG_state
        final {
                Attribute *idAttr = $1->tag->findAttr( "id" );
                if ( idAttr == 0 )
-                       error($1->loc) << "tag <state> requires an id attribute" << endl;
+                       error($1->loc) << "tag <state> requires an id attribute" << endp;
                else {
                        int id = atoi( idAttr->value );
                        cgd->setId( curState, id );
@@ -401,7 +397,7 @@ tag_state_cond_list_head: TAG_cond_list
        final {
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 )
-                       error($1->loc) << "tag <cond_list> requires a length attribute" << endl;
+                       error($1->loc) << "tag <cond_list> requires a length attribute" << endp;
                else {
                        ulong length = readLength( lengthAttr->value );
                        cgd->initStateCondList( curState, length );
@@ -430,7 +426,7 @@ tag_trans_list_head: TAG_trans_list
        final {
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 )
-                       error($1->loc) << "tag <trans_list> requires a length attribute" << endl;
+                       error($1->loc) << "tag <trans_list> requires a length attribute" << endp;
                else {
                        unsigned long length = strtoul( lengthAttr->value, 0, 10 );
                        cgd->initTransList( curState, length );
@@ -462,7 +458,7 @@ tag_action_list_head: TAG_action_list
        final {
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 )
-                       error($1->loc) << "tag <action_list> requires a length attribute" << endl;
+                       error($1->loc) << "tag <action_list> requires a length attribute" << endp;
                else {
                        unsigned long length = strtoul( lengthAttr->value, 0, 10 );
                        cgd->initActionList( length );
@@ -483,7 +479,7 @@ tag_action: TAG_action inline_list '/' TAG_action
                Attribute *colAttr = $1->tag->findAttr( "col" );
                Attribute *nameAttr = $1->tag->findAttr( "name" );
                if ( lineAttr == 0 || colAttr == 0)
-                       error($1->loc) << "tag <action> requires a line and col attributes" << endl;
+                       error($1->loc) << "tag <action> requires a line and col attributes" << endp;
                else {
                        unsigned long line = strtoul( lineAttr->value, 0, 10 );
                        unsigned long col = strtoul( colAttr->value, 0, 10 );
@@ -773,7 +769,7 @@ tag_action_table_list_head: TAG_action_table_list
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 ) {
                        error($1->loc) << "tag <action_table_list> requires "
-                                       "a length attribute" << endl;
+                                       "a length attribute" << endp;
                }
                else {
                        unsigned long length = strtoul( lengthAttr->value, 0, 10 );
@@ -790,7 +786,7 @@ tag_action_table: TAG_action_table '/' TAG_action_table
                /* Find the length of the action table. */
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 )
-                       error($1->loc) << "tag <at> requires a length attribute" << endl;
+                       error($1->loc) << "tag <at> requires a length attribute" << endp;
                else {
                        unsigned long length = strtoul( lengthAttr->value, 0, 10 );
 
@@ -825,7 +821,7 @@ tag_cond_space_list_head: TAG_cond_space_list
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                if ( lengthAttr == 0 ) {
                        error($1->loc) << "tag <cond_space_list> "
-                                       "requires a length attribute" << endl;
+                                       "requires a length attribute" << endp;
                }
                else {
                        ulong length = readLength( lengthAttr->value );
@@ -842,10 +838,10 @@ tag_cond_space: TAG_cond_space '/' TAG_cond_space
                Attribute *lengthAttr = $1->tag->findAttr( "length" );
                Attribute *idAttr = $1->tag->findAttr( "id" );
                if ( lengthAttr == 0 )
-                       error($1->loc) << "tag <cond_space> requires a length attribute" << endl;
+                       error($1->loc) << "tag <cond_space> requires a length attribute" << endp;
                else {
                        if ( lengthAttr == 0 )
-                               error($1->loc) << "tag <cond_space> requires an id attribute" << endl;
+                               error($1->loc) << "tag <cond_space> requires an id attribute" << endp;
                        else {
                                unsigned long condSpaceId = strtoul( idAttr->value, 0, 10 );
                                ulong length = readLength( lengthAttr->value );
@@ -917,7 +913,7 @@ ostream &Parser::warning( const InputLoc &loc )
 
 ostream &Parser::error( const InputLoc &loc )
 {
-       errCount += 1;
+       gblErrorCount += 1;
        assert( fileName != 0 );
        cerr << fileName << ":" << loc.line << ":" << loc.col << ": ";
        return cerr;
@@ -926,7 +922,7 @@ ostream &Parser::error( const InputLoc &loc )
 
 ostream &Parser::parser_error( int tokId, Token &token )
 {
-       errCount += 1;
+       gblErrorCount += 1;
        assert( fileName != 0 );
        cerr << fileName << ":" << token.loc.line << ":" << token.loc.col;
        if ( token.tag != 0 ) {
@@ -943,10 +939,8 @@ ostream &Parser::parser_error( int tokId, Token &token )
 int Parser::token( int tokenId, Token &tok )
 {
        int res = parseLangEl( tokenId, &tok );
-       if ( res < 0 ) {
-               parser_error( tokenId, tok ) << "parse error" << endl;
-               exit(1);
-       }
+       if ( res < 0 )
+               parser_error( tokenId, tok ) << "parse error" << endp;
        return res;
 }
 
index f52cd6c..474a49c 100644 (file)
@@ -345,6 +345,7 @@ int xml_parse( std::istream &input, char *fileName,
 
 std::ostream &Scanner::error()
 {
+       gblErrorCount += 1;
        cerr << fileName << ":" << curline << ":" << curcol << ": ";
        return cerr;
 }
index e1138fc..ce5959b 100644 (file)
@@ -99,9 +99,6 @@ void version()
                        "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
 }
 
-/* Total error count. */
-int gblErrorCount = 0;
-
 ostream &error()
 {
        gblErrorCount += 1;
index 0b97201..3133808 100644 (file)
@@ -77,9 +77,6 @@ void version()
                        "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
 }
 
-/* Total error count. */
-int gblErrorCount = 0;
-
 ostream &error()
 {
        gblErrorCount += 1;
index 5b4de33..6c4eeed 100644 (file)
@@ -75,9 +75,6 @@ void version()
                        "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
 }
 
-/* Total error count. */
-int gblErrorCount = 0;
-
 ostream &error()
 {
        gblErrorCount += 1;
index 8031451..5a26ea8 100644 (file)
@@ -75,9 +75,6 @@ void version()
                        "Copyright (c) 2001-2007 by Adrian Thurston" << endl;
 }
 
-/* Total error count. */
-int gblErrorCount = 0;
-
 ostream &error()
 {
        gblErrorCount += 1;