Search code examples
regexparsingfsmragel

Can Ragel perform individual command parsing and throw errors accordingly


I am trying to parse a command :LoadSdf 12 abc.ldf I am trying to get errors at each stage( :LoadSdf,12, abc.ldf ) of the command. But I get a different behaviour as shown in the later part of the question.

Following is my Ragel pseudo code

    %%
    machine ldf;

    LOAD_CMD = ":LoadSdf" $!(cmd_error);
    CHANNEL_NR = [digit]+ $!(channel_error);
    FILENAME = [a-zA-Z0-9\.\-\_]+ $!(filename_error);
    SPACE = ' ';

    main:= (LOAD_CMD.SPACE+.CHANNEL_NR.SPACE.FILENAME) %/job_done;
    %%

Expected output :

    ./a.out ":Load"
    incorrect command  //corresponding actions contain these error messages

    ./a.out ":LoadSdf"
    whitespace missing //corresponding actions contain these error messages

    ./a.out ":LoadSdf "
    channel number missing //corresponding actions contain these error messages

    ./a.out ":LoadSdf 12 "
    file name missing  //corresponding actions contain these error messages

    ./a.out ":LoadSdf 12 abc.ldf"
    parsing success  //corresponding actions contain these messages

Observed output :

    ./a.out ":Load"
    incorrect command

    ./a.out ":LoadSdf"      
    whitespace missing

    ./a.out ":LoadSdf "
    whitespace missing
    channel number missing

    ./a.out ":LoadSdf 12 "
    whitespace missing
    file name missing

    ./a.out ":LoadSdf 12"
    channel number missing

    ./a.out ":LoadSdf 12 abc.ldf"
    parsing success 

The Ragel syntax for error handling is quite difficult and explained very limitedly. It would be of a great help if any suggestions for the current case are provided.


Solution

  • More debugging with the help of state machines and I could come up with the answer. Basically >! could be used for error handling in case of start condition only.

    LOAD_CMD = ":LoadSdf" @!(cmd_error);
    CHANNEL_NR = [digit]+ >!(channel_error);
    FILENAME = [a-zA-Z0-9\.\-\_]+ $!(filename_error);
    SPACE = ' ' >!(whitespace_error);