2

Assume we want to validate user input, while user is typing in a JTextField. For validating the user input, I wonder if I could use Ragel.

Assume the input should follow this example regex:

[a-z]{2,5}ABC[0-9]+

How can I do this with ragel? Can anybody give a short example how to validate user input "on the fly" (while inputing) with ragel?

The Ragel documentations misses some good examples for a Quick Start, so I ask here.

Kai Mechel
  • 753
  • 8
  • 19
  • why would you need to do this using regal? isnt regex good enough? – Chii Jan 02 '09 at 09:31
  • I try to avoid invalid input. With a regex I can validate all at once and tell the user that the input is not valid. But I would like to reject invalid characters. My problem is the complex regex. I think the only way to do this is a state machine. I want to automate the creation of the statemachine – Kai Mechel Jan 05 '09 at 21:01

1 Answers1

5

You can use EOF actions (section 3.2.2 EOF Actions in the Ragel documentation) for checking of the expressions on the fly with Ragel. They are triggered when end of input buffer is detected in a valid state (including non-final).

Simple example:

  main := ([a-z]{2,5}'ABC'[0-9]+) @/{correct = 1;} %{correct = 1;};

Action "@/" is for all non-final states. It includes starting state so empty string is correct for this case. Action "%" is for final state when entire input buffer matches the pattern. In the example above code for both actions are the same, but final state is often to be processed separately in practice. If it is not needed then the sample above can be simplified:

  main := ([a-z]{2,5}'ABC'[0-9]+) $/{correct = 1;};

The complete Ragel sample with C output for checking the provided pattern is below. I hope that it is not a problem to convert it to Java.

  #include <stdio.h>

  %%{
   machine checker;
   write data;
  }%%

  unsigned char checker( const char *str )
  {
   /* standart Ragel variables */
   const char *p = str, *pe = str + strlen( str ) - 1; //-1 to strip "\n"
   const char *eof = pe;
   int cs;

   unsigned char correct = 0;

   %%{
    action final { printf("entire match"); correct = 1; }
    action partial { printf("partial match"); correct = 1; }

    main := ([a-z]{2,5}'ABC'[0-9]+) @/partial %final;

    write init;
    write exec;
   }%%

   return correct;
  };


  #define BUFSIZE 1024
  int main()
  {
   char buf[BUFSIZE];
   while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
    printf( "%d\n", checker( buf ));
   }
   return 0;
  }
Artem Zankovich
  • 2,319
  • 20
  • 36