Я сделал очень продвинутые синтаксические анализаторы Rebol, которые управляют живыми и критичными TCP-серверами и делают правильную отчетность об ошибках. Так что это важно!
Возможно, одним из самых уникальных аспектов PARSE Ребола является то, что вы можете включать прямую оценку в правила. Таким образом, вы можете установить переменные для отслеживания позиции синтаксического анализа или сообщений об ошибках и т. Д. (Это очень просто, потому что характер Rebol заключается в том, что код смешивания и данные как одна и та же вещь являются основной идеей.)
So вот как я это сделал. Перед попыткой каждого правила сопоставления я сохраняю позицию синтаксического анализа в «здесь» (путем записи here:
), а затем также сохраняю ошибку в переменной с помощью выполнения кода (путем помещения (error: {some error string})
в круглые скобки, чтобы он выполнял диалоги на основе анализа). Если правило совпадения выполняется успешно, нам не нужно использовать ошибку или позицию ... и мы просто переходим к следующему правилу. Но если это не удастся, мы получим последнее состояние, которое мы установили для отчета после сбоя.
Таким образом, картина в синтаксическое диалекте просто:
; use PARSE dialect handling of "set-word!" instances to save parse
; position into variable named "here"
here:
; escape out of the parse dialect using parentheses, and into the DO
; dialect to run arbitrary code. Here we run code that saves an error
; message string into a variable named "error"
(error: "<some error message relating to rule that follows>")
; back into the PARSE dialect again, express whatever your rule is,
; and if it fails then we will have the above to use in error reporting
what: (ever your) [rule | {is}]
Это в основном то, что вам нужно сделать.Вот пример телефонных номеров:
digit: charset ""
phone-number-rule: [
here:
(error: "invalid area code")
["514" | "800" | "888" | "916" "877"]
here:
(error: "expecting dash")
"-"
here:
(error: "expecting 3 digits")
3 digit
here:
(error: "expecting dash")
"-"
here:
(error: "expecting 4 digits")
4 digit
(error: none)
]
Тогда вы можете увидеть его в действии. Обратите внимание, что мы не устанавливаем ошибку в none, если мы достигнем конца правил разбора. PARSE вернет ложь, если есть еще больший вклад в процесс, так что если мы замечаем, что нет никакой ошибки установлен, но PARSE возвращает ложь в любом случае ... мы не смогли, потому что было слишком много дополнительного входа:
input: "800-22r2-3333"
if not parse input phone-number-rule [
if none? error [
error: "too much data for phone number"
]
]
either error [
column: length? copy/part input here newline
print rejoin ["error at position:" space column]
print error
print input
print rejoin [head insert/dup "" space column "^^"}
print newline
][
print {all good}
]
выше будет распечатаны следующие:
error at position: 4
expecting 3 digits
800-22r2-3333
^
Очевидно, что вы могли бы сделать гораздо более мощное вещество, так как все, что вы положили в круглые скобки будут оценены только как обычный исходный код Rebol. Это действительно гибко. У меня даже есть парсеры, которые обновляют индикаторы выполнения при загрузке огромных наборов данных ... :-)
Вы спрашиваете «строка и столбец недействительного токена/правила». Вы спрашиваете, как сказать, когда есть проблема с набранным блоком правил, который вы проходите, или инструментами, которые эти правила могут использовать для сообщения о проблемах во входном сигнале для самого процесса анализа? Редактирование этого вопроса для добавления идеализированного примера того, что вы ищете, может быть полезным. – HostileFork
@HostileFork Я прошу второй случай, когда вход недействителен. – Erick