Search code examples
rascal

Match Symbol specific number of times


When defining a syntax, it is possible to match 1 or more times (+) or 0 or more times (*) similarly to how it is done in regex. However, I have not found in the rascal documentation if it is possible to also match a Symbol a specific amount of times. In regex (and Rascal patterns) this is done with an integer between two curly brackets but this doesn't seem to work for syntax definition. Ideally, I'd want something like:

lexical Line = [0-9.]+;
syntax Sym = sym: {Line Newline}{5};

Which would only try to match the first 5 lines of the text below:

..0..
11.11
44.44
1.11.1
33333
55555

Solution

  • No this meta syntax does not exist in Rascal. We did not add it.

    You could write an over-estimation like this and have a post-parse filter reject more than 5 items:

    syntax Sym = fiveLines: (Line NewLine)+ lines
    
    visit (myParseTree) {
       case (Sym) `<(Line NewLine)+ lines>` : 
          throw ParseError(x.src) when length(lines) != 5;
    }
    

    Or unfold the loop like so:

    syntax Sym 
        =  Line NewLine
           Line NewLine
           Line NewLine 
           Line NewLine
           Line NewLine
        ;
    

    Repetition with an integer parameter sounds like a good feature request for us the consider, if you need it badly. We only have to consider what it means for Rascal's type-system; for the parser generator its a simple rule to add.