0Pricing
TypeScript Academy · درس

مفاهيم مُركّبات المحلل

ركّبوا محللات صغيرة في محللات أكبر

مفاهيم مُركّبات المحلل درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ما هو المحلّل

يقرأ المحلّل المدخلات (وهي عادةً سلسلة نصية) وينتج مخرجات منظّمة، أو يفشل. سنبدأ على مستوى القيم لبناء الحدس، ثم ننقل الأفكار نفسها إلى نظام الأنواع.

type Parser<T> = (input: string) => { value: T; rest: string } | null;
// Consumes part of the input, returns a value and the leftover

محلّل صغير

يطابق أبسط محلّل بادئة حرفية. فإذا بدأ الإدخال بالنص المتوقع، نجح المحلّل وأعاد السلسلة المتبقية؛ وإلا أعاد 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"));

المركّبات

يأخذ المركّب محللات صغيرة ويبني منها محللات أكبر. ولهذا الأسلوب التركيبي اسم مركّبات المحللات: إذ تجمعون محللات معقدة من أجزاء بسيطة قابلة لإعادة الاستخدام.

// Small parsers: digit, letter, literal
// Combinators: sequence, choice, many
// Compose them into: number, identifier, expression

التسلسل

يشغّل مركّب التسلسل محلّلًا، ثم يشغّل محلّلًا آخر على الجزء المتبقي، ويجمع نتيجتيهما في زوج. ويجب أن ينجح كلاهما حتى ينجح التسلسل.

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 };
  };
}

استخدام التسلسل

اجمع قيمتين حرفيتين لتحليلهما بالترتيب. تحتفظ النتيجة بالجزأين المطابقين وبالإدخال المتبقي.

const ab = seq(literal("a"), literal("b"));
const r = ab("abc");
console.log(r); // { value: ["a","b"], rest: "c" }

الاختيار

يجرّب مُركِّب الاختيار المحلّل الأول؛ وإذا فشل، يجرّب الثاني. يعبّر هذا عن البدائل، مثل «رقم أو حرف».

function alt<T>(p1: Parser<T>, p2: Parser<T>): Parser<T> {
  return input => p1(input) ?? p2(input);
}

التكرار

يطبّق مُركِّب many محلّلًا بشكل متكرر حتى يفشل، ويجمع جميع النتائج. يتيح ذلك تحليل القوائم أو تسلسلات الأرقام أو المسافات البيضاء.

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 };
  };
}

تحويل النتائج

يحوّل مُركِّب map نتيجة المحلّل من دون تغيير ما يستهلكه، مثل تحويل محارف الأرقام المطابقة إلى رقم.

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;
  };
}

البناء تدريجيًا

باستخدام هذه المُركِّبات القليلة (literal وseq وalt وmany وmap)، يمكنكم تحليل قواعد نحوية حقيقية: الأرقام، والمعرّفات، وحتى لغات تعبيرات صغيرة. كل طبقة تؤلّف الطبقة التي تحتها.

const digit = alt(literal("0"), literal("1")); // toy digit
const digits = many(digit);
console.log(digits("0110x"));

من القيم إلى الأنواع

الفكرة الأساسية هي أن البنية التركيبية نفسها تعمل على مستوى الأنواع أيضًا. هناك، يكون «الإدخال» نوعًا حرفيًا لسلسلة نصية، وتكون المحلّلات أنواعًا شرطية تستخدم استدلال القوالب الحرفية. سننتقل إلى ذلك بعد قليل.

// Value level: (input: string) => { value, rest } | null
// Type level:  conditional types over string literal types

لماذا التحليل على مستوى الأنواع

تتيح المحلّلات على مستوى الأنواع للمصرّف فهم بنية السلاسل النصية الحرفية: مسارات التوجيه، وسلاسل التنسيق، ومفاتيح الاستعلام. وينتقل الحدس الذي بنيتموه حول المُركِّبات هنا مباشرةً إلى تقنيات مستوى الأنواع في بقية هذه الدورة.

// Goal: parse "users/:id" into { id: string } at compile time

تحقّق سريع

اختبروا فهمكم لمُركِّبات المحلّلات.

مراجعة

بنيتم حدسًا حول المحلّلات على مستوى القيم.

  • يستهلك المحلّل الإدخال ويعيد قيمة مع الجزء المتبقي، أو يفشل.
  • تؤلّف المُركِّبات (seq وalt وmany وmap) محلّلات صغيرة لتكوين محلّلات كبيرة.
  • تنطبق البنية نفسها على مستوى الأنواع.

التالي: تقسيم السلاسل النصية في نظام الأنواع.

الأسئلة الشائعة

هل درس «مفاهيم مُركّبات المحلل» مجاني؟

نعم — نص درس «مفاهيم مُركّبات المحلل» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «مفاهيم مُركّبات المحلل»؟

ركّبوا محللات صغيرة في محللات أكبر تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «مفاهيم مُركّبات المحلل»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مفاهيم مُركّبات المحلل
  2. تقسيم السلاسل على مستوى النوع
  3. التحليل باستخدام القوالب الحرفية
  4. محلل مسارات مصغّر على مستوى النوع
← العودة إلى TypeScript Academy