[ragel-users] Question about nested state charts

Adrian Thurston thurs... at cs.queensu.ca
Thu Dec 21 05:11:30 UTC 2006

Hi Zed,

I think nesting is a really good idea. Though Ragel can't build your 
machine exactly the way you've specified it. It's a limitation of the 
Ragel language and not of the underlying machines. When the end of a 
comma-separated list of machines is found Ragel tries to resolve all 
epsilon transitions inside it. So the epsilon drawn to Aborting is 
resolved when the inner join is complete, only the Aborting label 
doesn't exist at that time. What you want is for it to be resolved on 
the outer join but the language doesn't give you a way to say that.

But since you've only got one destination on the exit from the inner 
join you can change it to this:

Connection = (

   start: ( open -> Accepting ),

   Accepting: (
     start: ( logged_in -> Processing ),
     Processing: ( receive -> Delivering | close -> final ),
     Delivering: ( delivered -> Processing ),
   ) -> Aborting,

   Aborting: ( finalized -> final )

) >begin %finish @!error;

If you need more than one exit then you'll have to subsume the inner 
state chart.

About the duplication ... I've actually been meaning to add a feature 
for importing machine definitions. Though I wanted to wait until I 
finished rewriting the parsers before I start adding to them. I'm 
currently migrating to Ragel/Kelbt. In the meantime duplication is all 
there is ... which I'm aware is quite painful to many coders.


Zed A. Shaw wrote:
> Hi,
> I'm looking for some advice on doing a nested state chart.  First, 
> here's a sample:
> Connection = (
>  start: ( open -> Accepting ),
>  Accepting: (
>    start: ( logged_in -> Processing ),
>    Processing: ( receive -> Delivering | close -> Connection::Aborting ),
>    Delivering: ( delivered -> Processing ),
>  ),
>  Aborting: ( finalized -> final )
> ) >begin %finish @!error;
> So my first question is if I'm just crazy for doing it this way?  The 
> manual doesn't *really* say you can nest state chart style machines like 
> this, so the "| close -> Aborting" doesn't actually resolve.  The manual 
> does talk about Resolving Names but "Connection::Aborting" doesn't work 
> for breaking out of the Accepting::Processing state and into Aborting.
> Also, I'm doing this as an experiment in using Ragel machines for 
> specifying a server's logic execution.  Not sure what the end result 
> will be, but it's already simplified quite a bit of code.  My only 
> complaint is that there's tons of duplication between the source and the 
> ragel file.  For example, I have to say logged_in='L' in the .rl and 
> then again in a .h somewhere.  It would be nicer if I can tell ragel, 
> "Anything you can resolve should be used symbolically since I defined it 
> someplace else."  Could work for actions too where ragel assumes any 
> action it knows nothing about is a direct function call with a certain 
> signature.
> Thanks!

More information about the ragel-users mailing list