Обработка зарезервированных ключевых слов зависит от лексического определения

Мой вопрос касается обработки зарезервированных ключевых слов в определениях синтаксиса Rascal. Возьмите следующий модуль Rascal, который был получен из онлайн-документации:

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";

Дело в том, что конструкция зарезервированных ключевых слов \ MyKeywords работает только если лексический [a-z] !<< [a-z]+ !>> [a-z], Если лексическое становится немного сложнее [a-z0-9] !<< [a-z][a-z0-9]* !>> [a-z0-9] тогда ключевые слова больше не исключаются.

Что я здесь не так делаю? Как я могу исключить ключевые слова в случае идентификаторов, таких как [a-z][a-z0-9]*?

1 ответ

Причиной проблемы является то, что сопоставление символов, таких как [a-z] рядом с [a-z0-9]+ связывает менее сильный, чем \ оператор и !>> оператор.

Итак, здесь мы резервируем MyKeywords только из хвоста [a-z0-9]+ идентификатора:

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

чтобы исправить это, вы можете добавить скобки для удаления MyKeywords из всей последовательности:

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

и затем вы можете добавить ограничение снова:

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

или примерно так:

lexical Identifier = [a-z] !<< ([a-z][a-z0-9]+) !>> [a-z] \ MyKeywords;
Другие вопросы по тегам