Zrobiłem bardzo zaawansowane parsery Rebol, które zarządzają serwerami TCP na żywo i krytycznymi operacjami, i wymagane było poprawne raportowanie błędów. To ważne!
Prawdopodobnie jednym z najbardziej unikalnych aspektów PARSU Rebola jest możliwość włączenia bezpośredniej oceny do reguł. Więc można ustawić zmienne do śledzenia położenia składniowy lub komunikaty o błędach itd (Jest to bardzo łatwe, ponieważ charakter REBOL jest to, że mieszanie kodu i danych, jak samo jest podstawowym pomysłem.)
tak oto sposób, w jaki to zrobiłem. Przed podjęciem każdej reguły dopasowania zapisuję pozycję parsowania w "tutaj" (pisząc here:
), a następnie zapisuję błąd w zmiennej za pomocą kodu (umieszczając (error: {some error string})
w nawiasach, tak aby dialekt parse działał). Jeśli reguła dopasowania się powiedzie, nie musimy używać błędu ani pozycji ... i przechodzimy do następnej reguły. Jeśli jednak zawiedzie, będziemy mieli ostatni stan, który ustawimy do zgłoszenia po awarii.
Zatem wzór w dialekcie parse jest prosta:
; 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}]
To w zasadzie to, co trzeba zrobić.Oto przykład numerów telefonów:
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)
]
Następnie można go zobaczyć w akcji. Zauważ, że ustawiamy błąd na none, jeśli dojdziemy do końca reguł parsowania. PARSE zwróci false, jeśli jest jeszcze bardziej wejście do procesu, więc jeśli zauważymy, nie ma błędu ustawienia ale PARSE zwraca fałsz w każdym razie ... nie udało, bo nie było zbyt dużo dodatkowy wkład:
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}
]
Powyższy wola wydrukować następujące:
error at position: 4
expecting 3 digits
800-22r2-3333
^
Oczywiście, można zrobić dużo silniejsze rzeczy, ponieważ cokolwiek umieścić w parens będą oceniane tak jak normalnego kodu źródłowego REBOL. Jest bardzo elastyczny. Mam nawet parsery, które aktualizują paski postępu podczas ładowania ogromnych zestawów danych ... :-)
Pytasz "wiersz i kolumnę nieprawidłowego tokena/reguły". Czy pytasz o to, jak określić, kiedy pojawia się problem z wybranym blokiem reguł, które przekazujesz, lub narzędziami, których te reguły mogą użyć do zgłaszania problemów w danych wejściowych do samego procesu parsowania? Edytowanie tego pytania w celu dodania wyidealizowanego przykładu tego, czego szukasz, może być pomocne. – HostileFork
@HostileFork Proszę o drugi przypadek, gdy dane wejściowe są nieprawidłowe. – Erick