When multiple conditions are executed on a single character they need to have a
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Sat, 10 Mar 2007 03:58:06 +0000 (03:58 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Sat, 10 Mar 2007 03:58:06 +0000 (03:58 +0000)
forced order. Previously, ordering relied on pointer-based sets, which caused
results to vary by compiler. Ordering is now done using conditon action
declaration order. This fixes the failure of cond4.rl which occurred with
g++ 4.1 and other compiler versions.

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

ChangeLog
ragel/fsmgraph.h
ragel/parsedata.cpp
ragel/parsedata.h
ragel/parsetree.cpp
ragel/rlparse.kl

index 2c31b9a..773de30 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,10 +9,13 @@ For Next Release
   tendency to associtate spaces with concatenation. Without syntax
   highlighting to make it clear that the embedding type is a keyword, the
   problem is especially bad. The danger is that a verbose embedding could be
-  read as an embedding of the embedding type:
-      main := 'foo' $from some_action '\n';
-  With parentheses this statment reads much more clearly.
-      main := 'foo' $from(some_action) '\n';
+  read as an embedding of the embedding type. With parentheses verbose
+  embeddings read much more clearly.
+ -Conditions now have a forced order when more than one is executed on a
+  single character. Previously, ordering relied on pointers, which caused
+  results to vary by compiler. Ordering is now done using conditon action
+  declaration order. This fixes the failure of cond4.rl which occured with
+  g++ 4.1 and other compiler versions.
 
 Ragel 5.18 - February 13, 2007
 ==============================
index e47525a..f3a16b9 100644 (file)
@@ -23,6 +23,7 @@
 #define _FSMGRAPH_H
 
 #include <assert.h>
+#include <iostream>
 #include "common.h"
 #include "vector.h"
 #include "bstset.h"
@@ -35,6 +36,7 @@
 #include "sbsttable.h"
 #include "avlset.h"
 #include "avlmap.h"
+#include "ragel.h"
 
 //#define LOG_CONDS
 
@@ -46,6 +48,8 @@
 #define SB_ISMARKED   0x08
 #define SB_ONLIST     0x10
 
+using std::ostream;
+
 struct TransAp;
 struct StateAp;
 struct FsmAp;
@@ -78,6 +82,94 @@ 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<NameInst*> ActionRefs;
+
+/* Element in list of actions. Contains the string for the code to exectute. */
+struct Action 
+:
+       public DListEl<Action>,
+       public AvlTreeEl<Action>
+{
+public:
+
+       Action( const InputLoc &loc, 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. */
+       char *getKey() const { return name; }
+
+       /* Data collected during parse. */
+       InputLoc loc;
+       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<Action> ActionList;
+typedef AvlTree<Action, char *, CmpStr> ActionDict;
+
+/* Structure for reverse action mapping. */
+struct RevActionMapEl
+{
+       char *name;
+       InputLoc location;
+};
+
+
 /* Transition Action Table.  */
 struct ActionTable 
        : public SBstMap< int, Action*, CmpOrd<int> >
@@ -444,8 +536,8 @@ typedef BstSet<int> EntryIdSet;
 typedef BstSet<LongestMatchPart*> LmItemSet;
 
 /* Conditions. */
-typedef BstSet< Action*, CmpOrd<Action*> > CondSet;
-typedef CmpTable< Action*, CmpOrd<Action*> > CmpCondSet;
+typedef BstSet< Action*, CmpCondId > CondSet;
+typedef CmpTable< Action*, CmpCondId > CmpCondSet;
 
 struct CondSpace
        : public AvlTreeEl<CondSpace>
index 5332286..881f5ab 100644 (file)
@@ -424,6 +424,7 @@ ParseData::ParseData( char *fileName, char *sectionName,
        /* 0 is reserved for global error actions. */
        nextLocalErrKey(1),
        nextNameId(0),
+       nextCondId(0),
        alphTypeSet(false),
        getKeyExpr(0),
        accessExpr(0),
@@ -933,7 +934,7 @@ Action *ParseData::newAction( char *name, InlineList *inlineList )
        loc.line = 1;
        loc.col = 1;
 
-       Action *action = new Action( loc, name, inlineList );
+       Action *action = new Action( loc, name, inlineList, nextCondId++ );
        action->actionRefs.append( rootName );
        actionList.append( action );
        return action;
@@ -1326,7 +1327,6 @@ void ParseData::prepareMachineGen( GraphDictEl *graphDictEl )
        sectionGraph->depthFirstOrdering();
        sectionGraph->sortStatesByFinal();
        sectionGraph->setStateNumbers( 0 );
-
 }
 
 void ParseData::generateXML( ostream &out )
index b6e1b28..55c69ef 100644 (file)
 /* Forwards. */
 using std::ostream;
 
-/* Nodes in the tree that use this action. */
-typedef Vector<NameInst*> ActionRefs;
-
-/* Element in list of actions. Contains the string for the code to exectute. */
-struct Action 
-:
-       public DListEl<Action>,
-       public AvlTreeEl<Action>
-{
-public:
-
-       Action( const InputLoc &loc, char *name, InlineList *inlineList )
-       :
-               loc(loc),
-               name(name),
-               inlineList(inlineList), 
-               actionId(-1),
-               numTransRefs(0),
-               numToStateRefs(0),
-               numFromStateRefs(0),
-               numEofRefs(0),
-               numCondRefs(0),
-               anyCall(false),
-               isLmAction(false)
-       {
-       }
-
-       /* Key for action dictionary. */
-       char *getKey() const { return name; }
-
-       /* Data collected during parse. */
-       InputLoc loc;
-       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;
-};
-
-/* A list of actions. */
-typedef DList<Action> ActionList;
-typedef AvlTree<Action, char *, CmpStr> ActionDict;
-
-/* Structure for reverse action mapping. */
-struct RevActionMapEl
-{
-       char *name;
-       InputLoc location;
-};
-
 struct VarDef;
 struct Join;
 struct Expression;
@@ -308,7 +237,7 @@ struct ParseData
        ActionList actionList;
 
        /* The id of the next priority name and label. */
-       int nextPriorKey, nextLocalErrKey, nextNameId;
+       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. */
index 6ff6fc5..16bc17d 100644 (file)
@@ -164,7 +164,7 @@ InputLoc LongestMatchPart::getLoc()
 Action *LongestMatch::newAction( ParseData *pd, const InputLoc &loc, 
                char *name, InlineList *inlineList )
 {
-       Action *action = new Action( loc, name, inlineList );
+       Action *action = new Action( loc, name, inlineList, pd->nextCondId++ );
        action->actionRefs.append( pd->curNameInst );
        pd->actionList.append( action );
        action->isLmAction = true;
@@ -1172,8 +1172,10 @@ FsmAp *FactorWithAug::walk( ParseData *pd )
                        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
index 37e5287..4fb7976 100644 (file)
@@ -109,7 +109,8 @@ action_spec:
                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 );
+                       Action *newAction = new Action( $3->loc, $2->data, 
+                                       $4->inlineList, pd->nextCondId++ );
 
                        /* Insert to list and dict. */
                        pd->actionList.append( newAction );
@@ -688,7 +689,7 @@ 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 );
+               Action *newAction = new Action( $1->loc, 0, $2->inlineList, pd->nextCondId++ );
                pd->actionList.append( newAction );
                $$->action = newAction;
        };