Указатель p
p
в RecordDigit
- это переменная, требуемая Ragel. Это указатель «на символьные данные для обработки». (В Java и Ruby это смещение байтового массива, data
). Поэтому выражение (*p) - '0'
принимает код символа текущего символа (например, код '7'
равен 55 в ASCII), вычитает код символа '0'
(48 в ASCII), чтобы получить фактическое числовое значение, представленное как символ: 55 - 48 = 7
.
Операторы >
и @
Оператор >
используется для выполнения действия при входе машины из состояния запуска. Оператор @
используется для выполнения действия при переводе машины в конечное состояние.
Это означает, что:
((digit @RecordDigit)+) >ClearNumber
звонит первым ClearNumber
при входе и звонит RecordDigit
каждый раз, когда digit
совпадает. Это можно легко проверить, изменив действия следующим образом:
action ClearNumber {
printf("ClearNumber\n");
currentNumber = 0;
}
action RecordDigit {
printf("RecordDigit\n");
uint8_t digit = (*p) - '0';
currentNumber = (currentNumber * 10) + digit;
}
распечатывает:
ClearNumber
RecordDigit
RecordDigit
RecordDigit
для трехзначного числа.
Основная информация
При первой встрече новой цифры currentNumber
устанавливается на 0. Цифра изменяется на uint8_t
на (*p)
- '0' и сохраняется в currentNumber
. Когда приходит следующая цифра, ее числовое значение вычисляется и добавляется к текущему значению currentNumber
, умноженному на 10, и т. Д. Таким образом, целью этого примера Ragel является преобразование разделенных пробелами чисел в строке в целые числа.
Ссылка
Руководство пользователя Ragel содержит всю информацию об элементах выше и довольно легко читается. Я сам новичок в Ragel, и у меня не было проблем с написанием моих собственных образцов.