Search code examples
rascal

Retaining separator while imploding


I have a syntax definition that looks like this

keyword LegendOperation = 'or' | 'and';
syntax LegendData
    = legend_data: LegendKey '=' {ID LegendOperation}+ Newlines
    ;

I need to implode this into a way that allows me to retain the information on whether the separator for the ID is 'or' or 'and' but I didn't find anything in the docs on whether the separator is retained and if it can be used by implode. Initially, I did something like the below to try and keep that informatioACn.

syntax LegendData
    = legend_data_or: LegendKey '=' {ID 'or'}+ Newlines
    > legend_data_and: LegendKey '=' {ID 'and'}+ Newlines
    ;

The issue that I run into is that there are three forms of text that it needs to be able to parse

. = Background
@ = Crate and Target
# = Crate or Wall

And when it tries to parse the first line it hits an ambiguity error when it should instead parse it as a legend_data_or with a single element (perhaps I misunderstood how to use the priorities). Honestly, I would prefer to be able to use that second format, but is there a way to disambiguate it?

Either a way to implode the first syntax while retaining the separator or a way to disambiguate the second format would help me with this issue.


Solution

  • I did not manage to come up with an elegant solution in the end. Discussing with others the best we could come up with was

    syntax LegendOperation
        = legend_or: 'or' ID
        | legend_and: 'and' ID
        ;
    
    syntax LegendData
        = legend_data: LegendKey '=' ID LegendOperation*  Newlines
        ;
    

    Which works and allows us to retain the information on the separator but requires post-processing to turn into a usable datatype.