Rascal: resolve ambiguity with comment

63 views Asked by At

Consider the following grammar:

module Tst
  
lexical Id  = [a-z][a-z0-9]* !>> [a-z0-9];

layout Layout = WhitespaceAndComment* !>> [\ \t\n\r];
 
lexical WhitespaceAndComment 
   = [\ \t\n\r]
     | @category="Comment" ^ "*" ![\n]* $
     ;
 
start syntax TstStart = Id*;

then

start[TstStart] t = parse(#start[TstStart], "*bla\nABC");

gives an ambiguity, probably because the comment can be placed before or after the empty list of strings. So, I have 2 questions:

  1. How can I use diagnose() to get a diagnosis? I have tried diagnose(t) and diagnose(parse(#start[TstStart], "*bla\nABC")), without success.
  2. What is the ambiguity and how can I resolve it?
3

There are 3 answers

0
Steven Klusener On

Sorry, it has been a while ago. The comment definition contains a flaw, it has to be corrected as follows:

@category="Comment" ^ "*" ![\n]* $

This resolves the ambiguity, but I still would like to know how to use diagnosis().

1
Steven Klusener On

When I make the example slightly more complicated I get another ambiguity.

module Tst
  
lexical Id  = [a-z][a-z0-9]* !>> [a-z0-9];
lexical String = "\"" ![\"]*  "\"";

layout Layout = WhitespaceAndComment* !>> [\ \t\n\r];
 
lexical WhitespaceAndComment 
   = [\ \t\n\r]
     | @category="Comment" ^ "*" ![\n]* $
     ;
 
start syntax TstStart = String* Id*;

Then "*bla\nABC" gives an ambiguity again. Probably because the comment can be placed before, within and after the empty list of strings. How to resolve it?

0
Jurgen Vinju On
  • The ambiguity is caused by ![*]* which can eat a \n or not, because the whitespace notion can also eat the \n or not.
  • The diagnose function is notoriously bad at spotting issues with whitespace. That can be improved.
  • The solution is to use ![*\n]* and end the comment line with "\n"
  • Another ambiguity will happen with actual * comments in the code, between String* and Id* the comments would go before or after the empty lists. To fix this: layout Layout = WhitespaceAndComment* !>> [\ \t\n\r] !>> [*]; adding the follow restriction with the [*] will help.