How to execute a % action only when a zero-length match/accept occurs.

Erich Ocean er... at atlasocean.com
Fri Feb 9 06:01:51 UTC 2007


Suppose we had the following machine:

%%{
machine test;

action FIRST {}
# Executed on recognition of the first character

action MATCH {}
# Executed on each character that puts the machine in a match state

action ACCEPT {}
# Executed when the machine accepts a match

main:= ( lower* >FIRST @MATCH %ACCEPT )? . ' ';
}%%

and we wanted the exact same machine, but with the ACCEPT action  
split into two:
- ACCEPT_AFTER_ZERO_LENGTH_MATCH_ONLY
- ACCEPT_AFTER_CHAR_MATCH_ONLY

Here's one way to do that in Ragel:

%%{
machine test;

action FIRST {}
# Executed on recognition of the first character

action MATCH {}
# Executed on each character that put the original machine in a match  
state

action ACCEPT_AFTER_CHAR_MATCH_ONLY {}
# Executed when the machine above accepted a match without  
recognizing any character

action ACCEPT_AFTER_ZERO_LENGTH_MATCH_ONLY {}
# Executed when the machine above accepted a match after recognizing  
a character

main := ( ('' %ACCEPT_AFTER_ZERO_LENGTH_MATCH_ONLY) | (lower+ >FIRST  
@MATCH %ACCEPT_AFTER_CHAR_MATCH_ONLY) ) . ' ';
}%%

The generated finite state machines are identical; only the actions  
executed are different. Notice that the Kleene star operator on lower  
has been changed to the one-or-more (+) operator.



More information about the ragel-users mailing list