action ordering. is this a bug?

Chris Pirazzi cpira... at gmail.com
Mon Feb 19 07:31:18 UTC 2007


On Feb 18, 11:29 pm, "Steve Horne" <stephenhorne... at aol.com> wrote:
> I understand Adrian won't be around for a couple of weeks. I'm no
> Ragel expert, but I'll make what I think is an educated guess and hope
> someone sets both of us straight ;-)

Hi,

Thanks for your response....see below..

> Even entry actions aren't triggered at the start of a rule - they are
> triggered on entry into the state where the rule has been fully
> recognised. Basically, the recognition tends to find the smallest
> building blocks first, progressing to larger building blocks later.
>
> In general, entry actions *cannot* be triggered on (for instance) the
> first character of a rule - you cannot know for sure which is the
> right rule. Consider what happens when there are two alternatives, for
> instance...
>
> opt1 = a.b;
> opt2 = a.c;
> main = opt1 | opt2;
>
> When the only input that has been examined is the 'a', you cannot tell
> whether you have an opt1 or an opt2. Therefore you cannot choose the
> correct entry action - this can only happen when you have also
> examined the 'b' or 'c' and entered the state where either opt1 or
> opt2 has been fully recognised.

Interesting theory, but I tried your grammar:

%%{

machine smaller;
write data noerror;

opt1 = ('a' . 'b') >{ printf(">opt1\n"); } @{ printf("@opt1\n"); }  $
{ printf("$opt1\n"); }  %{ printf("%%opt1\n"); };
opt2 = ('a' . 'c') >{ printf(">opt2\n"); } @{ printf("@opt2\n"); }  $
{ printf("$opt2\n"); }  %{ printf("%%opt2\n"); };
main := (opt1 | opt2) >{ printf(">main\n"); } @{ printf("@main\n"); }
${ printf("$main\n"); }  %{ printf("%%main\n"); };

write init;
write exec noend;

}%%
}%%

and it doesn't seem to work that way.  when you view the state
diagram, you see that
as soon as we see the 'a', regel calls ">main", then ">opt1", and
">opt2" (in this
case, unlike my initial example, this is the order I would expect with
the
parents' ">" routine being called first):

<ragel filename="smaller.rl" lang="C">
<ragel_def name="smaller">
  <alphtype>0</alphtype>
  <machine>
    <action_list length="9">
      <action id="0" line="7" col="21"><text> printf(">opt1\n"); </
text></action>
      <action id="1" line="7" col="45"><text> printf("@opt1\n"); </
text></action>
      <action id="2" line="7" col="70"><text> printf("$opt1\n"); </
text></action>
      <action id="3" line="8" col="21"><text> printf(">opt2\n"); </
text></action>
      <action id="4" line="8" col="45"><text> printf("@opt2\n"); </
text></action>
      <action id="5" line="8" col="70"><text> printf("$opt2\n"); </
text></action>
      <action id="6" line="9" col="24"><text> printf(">main\n"); </
text></action>
      <action id="7" line="9" col="48"><text> printf("@main\n"); </
text></action>
      <action id="8" line="9" col="73"><text> printf("$main\n"); </
text></action>
    </action_list>
    <action_table_list length="3">
      <action_table id="0" length="6">6 0 2 3 5 8</action_table>
      <action_table id="1" length="4">1 2 7 8</action_table>
      <action_table id="2" length="4">4 5 7 8</action_table>
    </action_table_list>
    <start_state>1</start_state>
    <error_state>0</error_state>
    <state_list length="5">
      <state id="0">
      <trans_list length="0">
      </trans_list>
      </state>

      <state id="1">
      <trans_list length="1">
        <t>97 97 2 0</t>
      </trans_list>
      </state>

      <state id="2">
      <trans_list length="2">
        <t>98 98 3 1</t>
        <t>99 99 4 2</t>
      </trans_list>
      </state>

      <state id="3" final="t">
      <trans_list length="0">
      </trans_list>
      </state>

      <state id="4" final="t">
      <trans_list length="0">
      </trans_list>
      </state>
    </state_list>
  </machine>
</ragel_def>
<host line="1" col="1">

</host>
<write def_name="smaller" line="5" col="1"><arg>data</
arg><arg>noerror</arg></write>
<write def_name="smaller" line="11" col="1"><arg>init</arg></write>
<write def_name="smaller" line="12" col="1"><arg>exec</arg><arg>noend</
arg></write>
<host line="14">

}</host>
<host line="16"></host>
</ragel>

it seems like if ragel waited to call the ">" routine until it found a
match, then
this would be the same as the "@" routine or the "$" routine.  the ">"
routine
is then useful for creating some state (e.g. allocating a memory
location)
which can later be filled in if the rule matches.

any other ideas?

     - Chris Pirazzi




More information about the ragel-users mailing list