Обработка зарезервированных ключевых слов зависит от лексического определения
Мой вопрос касается обработки зарезервированных ключевых слов в определениях синтаксиса 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;