Koncepcje kombinatorów parserów
Komponuj małe parsery w większe
Koncepcje kombinatorów parserów to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej TypeScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs TypeScript Academy zawiera 4 lekcji w sumie.
Czym jest parser
Parser odczytuje dane wejściowe (zwykle ciąg znaków) i tworzy uporządkowany wynik albo kończy działanie niepowodzeniem. Najpierw zaczniemy od poziomu wartości, aby zbudować intuicję, a następnie przeniesiemy te same idee do systemu typów.
type Parser<T> = (input: string) => { value: T; rest: string } | null;
// Consumes part of the input, returns a value and the leftoverMały parser
Najprostszy parser dopasowuje dosłowny prefiks. Jeśli dane wejściowe zaczynają się od oczekiwanego tekstu, parser kończy się powodzeniem i zwraca pozostały ciąg; w przeciwnym razie zwraca null.
function literal(prefix: string): Parser<string> {
return input =>
input.startsWith(prefix)
? { value: prefix, rest: input.slice(prefix.length) }
: null;
}
console.log(literal("ab")("abc"));Kombinatory
Kombinator przyjmuje małe parsery i buduje z nich większe. Ten kompozycyjny styl jest powodem, dla którego podejście nazywa się kombinatorami parserów: złożone parsery składa się z prostych, wielokrotnego użytku elementów.
// Small parsers: digit, letter, literal
// Combinators: sequence, choice, many
// Compose them into: number, identifier, expressionSekwencjonowanie
Kombinator sekwencji uruchamia jeden parser, a następnie kolejny na pozostałych danych, łącząc ich wyniki w parę. Oba parsery muszą zakończyć się powodzeniem, aby sekwencja zakończyła się powodzeniem.
function seq<A, B>(pa: Parser<A>, pb: Parser<B>): Parser<[A, B]> {
return input => {
const ra = pa(input);
if (!ra) return null;
const rb = pb(ra.rest);
if (!rb) return null;
return { value: [ra.value, rb.value], rest: rb.rest };
};
}Używanie sekwencji
Połącz dwa literały, aby przeanalizować je w określonej kolejności. Wynik zawiera oba dopasowane fragmenty oraz pozostałe dane wejściowe.
const ab = seq(literal("a"), literal("b"));
const r = ab("abc");
console.log(r); // { value: ["a","b"], rest: "c" }Wybór
Kombinator wyboru najpierw próbuje użyć pierwszego parsera; jeśli ten zawiedzie, próbuje drugiego. Pozwala to wyrażać alternatywy, takie jak „cyfra albo litera”.
function alt<T>(p1: Parser<T>, p2: Parser<T>): Parser<T> {
return input => p1(input) ?? p2(input);
}Powtarzanie
Kombinator many wielokrotnie stosuje parser, aż do jego niepowodzenia, zbierając wszystkie wyniki. Umożliwia to parsowanie list, ciągów cyfr lub białych znaków.
function many<T>(p: Parser<T>): Parser<T[]> {
return input => {
const out: T[] = [];
let rest = input;
let r = p(rest);
while (r) { out.push(r.value); rest = r.rest; r = p(rest); }
return { value: out, rest };
};
}Mapowanie wyników
Kombinator map przekształca wynik parsera bez zmiany tego, co parser konsumuje, na przykład zamienia dopasowane znaki cyfr w liczbę.
function map<A, B>(p: Parser<A>, f: (a: A) => B): Parser<B> {
return input => {
const r = p(input);
return r ? { value: f(r.value), rest: r.rest } : null;
};
}Rozbudowa
Na podstawie tych kilku kombinatorów (literal, seq, alt, many, map) można parsować rzeczywiste gramatyki: liczby, identyfikatory, a nawet małe języki wyrażeń. Każda warstwa buduje na warstwie znajdującej się niżej.
const digit = alt(literal("0"), literal("1")); // toy digit
const digits = many(digit);
console.log(digits("0110x"));Od wartości do typów
Kluczowa obserwacja jest taka, że ta sama struktura kompozycyjna działa również na poziomie typów. Na tym poziomie „danymi wejściowymi” są typy literałów tekstowych, a parserami — typy warunkowe wykorzystujące wnioskowanie z literałów szablonowych. Następnie przejdziemy do tego poziomu.
// Value level: (input: string) => { value, rest } | null
// Type level: conditional types over string literal typesDlaczego parsowanie na poziomie typów
Parsery na poziomie typów pozwalają kompilatorowi rozumieć strukturę literałów tekstowych: ścieżki routingu, ciągi formatujące czy klucze zapytań. Zbudowana tutaj intuicja dotycząca kombinatorów bezpośrednio przekłada się na techniki pracy na poziomie typów przedstawione w dalszej części kursu.
// Goal: parse "users/:id" into { id: string } at compile timeSzybki test
Proszę sprawdzić swoją wiedzę na temat kombinatorów parserów.
Podsumowanie
Zbudowano podstawową intuicję dotyczącą parserów na poziomie wartości.
- Parser konsumuje dane wejściowe i zwraca wartość wraz z pozostałymi danymi albo kończy działanie niepowodzeniem.
- Kombinatory (seq, alt, many, map) łączą małe parsery w większe.
- Ta sama struktura ma zastosowanie na poziomie typów.
Następnie: dzielenie ciągów znaków w systemie typów.
Często zadawane pytania
Czy lekcja „Koncepcje kombinatorów parserów” jest bezpłatna?
Tak — pełny tekst „Koncepcje kombinatorów parserów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu TypeScript Academy, przejdź na CoddyKit PRO. Kurs TypeScript Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Koncepcje kombinatorów parserów”?
Komponuj małe parsery w większe Ćwiczysz TypeScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć TypeScript Academy?
Nie wymagamy żadnego doświadczenia. TypeScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Koncepcje kombinatorów parserów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji TypeScript Academy?
Tak. Każda lekcja TypeScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Koncepcje kombinatorów parserów
- Dzielenie stringów na poziomie typów
- Parsowanie za pomocą literałów szablonowych
- Mini parser ścieżek routingu na poziomie typów