1

My question is about handling reserved keywords in Rascal syntax definitions. Take the following Rascal module, which has been derived from the on-line documentation:

module Test
// Taken from http://tutor.rascal-mpl.org/Rascal/Declarations/SyntaxDefinition/SyntaxDefinition.html

start syntax Top = Identifier | ReservedKeyword;

layout MyLayout = [\t\n\ \r\f]*;

// Is OK, parse(#Top,"if") succeeds, parse(#Identifier,"if") fails
lexical Identifier = [a-z] !<< [a-z]+ !>> [a-z] \ MyKeywords;

// Goes wrong, parse(#Top,"if") fails, parse(#Identifier,"if") succeeds, 
// so "if" is not exluded
//lexical Identifier = [a-z0-9] !<< [a-z][a-z0-9]* !>> [a-z0-9] \ MyKeywords;

keyword MyKeywords = "if" | "then" | "else" | "fi";

syntax ReservedKeyword = "if" | "then" | "else" | "fi";

The point is that the reserved keywords construction \ MyKeywords only works if the lexical is defined as [a-z] !<< [a-z]+ !>> [a-z]. If the lexical becomes slightly more complicated [a-z0-9] !<< [a-z][a-z0-9]* !>> [a-z0-9] then the keywords are no longer excluded.

What do I do wrong here? How can I exclude keywords in case of identifiers like [a-z][a-z0-9]*?

Jurgen Vinju
  • 6,393
  • 1
  • 15
  • 26

1 Answers1

0

The cause of the problem is that iuxtapositioning of symbols such as [a-z] next to [a-z0-9]+ binds less strong than the \ operator and the !>> operator.

So here we are reserving MyKeywords only from the tail [a-z0-9]+ of the identifier:

lexical Identifier = [a-z] !<< [a-z][a-z0-9]+ \ MyKeywords;

to fix this, you can add brackets to remove MyKeywords from the entire sequence:

lexical Identifier = [a-z] !<< ([a-z][a-z0-9]+) \ MyKeywords;

and then you can add the restriction again:

lexical Identifier = [a-z] !<< ([a-z][a-z0-9]+) \ MyKeywords !>> [a-z];

or like so, equivalently:

lexical Identifier = [a-z] !<< ([a-z][a-z0-9]+) !>> [a-z] \ MyKeywords;
Jurgen Vinju
  • 6,393
  • 1
  • 15
  • 26