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
==============================
#define _FSMGRAPH_H
#include <assert.h>
+#include <iostream>
#include "common.h"
#include "vector.h"
#include "bstset.h"
#include "sbsttable.h"
#include "avlset.h"
#include "avlmap.h"
+#include "ragel.h"
//#define LOG_CONDS
#define SB_ISMARKED 0x08
#define SB_ONLIST 0x10
+using std::ostream;
+
struct TransAp;
struct StateAp;
struct FsmAp;
/* 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> >
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>
/* 0 is reserved for global error actions. */
nextLocalErrKey(1),
nextNameId(0),
+ nextCondId(0),
alphTypeSet(false),
getKeyExpr(0),
accessExpr(0),
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;
sectionGraph->depthFirstOrdering();
sectionGraph->sortStatesByFinal();
sectionGraph->setStateNumbers( 0 );
-
}
void ParseData::generateXML( ostream &out )
/* 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;
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. */
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;
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
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 );
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;
};