Не знаком с Ragel, но сделал несколько пользовательских анализаторов и сканеров.
Похоже, ваш вопрос больше связан с обнаружением ключевых слов, чем с определением общих идентификаторов.
У вас есть правила, предписывающие Ragel определять, когда в разделе есть код, число, ключевое слово «return», точка с запятой, ключевое слово «return», идентификатор и так далее. Хотя для каждого ключевого слова можно создать правило, я не рекомендую.
Что я узнал на собственном опыте, так это то, что лучше читать все ключевые слова эксплицитность в качестве идентификаторов (назначить общий маркер "идентификатора"), а в какой-то части вашего кода C / C ++ определить, какие идентификаторы являются «ключевыми словами».
Другими словами. Ragel будет обнаруживать только идентификаторы. «myvar», «return» и «return» будут помечены как «идентификаторы». Позже, в коде вашего семантического действия ( C / C ++ не Ragel ), вы проверите каждый идентификатор и определите, является ли ключевое слово в C / C ++. Обычно это делается с помощью списка ключевых слов.
Я думаю, что это будет примерно так:
%%{
Identifier = (alpha | '_') . (alnum | '_')*;
action IdentifierAction
{
String Keywords[] =
(
"return",
"if",
"else"
);
String MyIdentifier = te - ts;
if (SearchKeywordCode(Keywords, MyIdentifier)) {
std::cout << "keyword(\"";
std::cout.write(ts, te - ts);
std::cout << "\")";
}
else {
std::cout << "identifier(\"";
std::cout.write(ts, te - ts);
std::cout << "\")";
}
}
}%%
Таким образом, не существует правила «Возврат» или «Возврат», а только «Идентификатор».