TypeScript Academy · บทเรียน

แนวคิดตัวประกอบการแยกวิเคราะห์

ประกอบตัวแยกวิเคราะห์ขนาดเล็กให้เป็นตัวแยกวิเคราะห์ที่ใหญ่ขึ้น

บทเรียน 1 จาก 413 ขั้นตอน

แนวคิดตัวประกอบการแยกวิเคราะห์ เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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;
  };
}

การต่อยอด

จากตัวประกอบเพียงไม่กี่ชนิดเหล่านี้ ได้แก่ ค่าลิเทอรัล การเรียงลำดับ การเลือก การทำซ้ำ และการแปลงผลลัพธ์ คุณสามารถแยกวิเคราะห์ไวยากรณ์จริงได้ ทั้งตัวเลข ตัวระบุ หรือแม้แต่ภาษานิพจน์ขนาดเล็ก แต่ละชั้นจะประกอบเข้ากับชั้นที่อยู่ด้านล่าง

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

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับตัวประกอบของตัวแยกวิเคราะห์

สรุปทบทวน

คุณได้สร้างความเข้าใจเกี่ยวกับตัวแยกวิเคราะห์ในระดับค่า

  • ตัวแยกวิเคราะห์จะใช้ข้อมูลเข้าและคืนค่าเป็นค่าหนึ่งพร้อมข้อมูลที่เหลือ หรือไม่สำเร็จ
  • ตัวประกอบสำหรับการเรียงลำดับ การเลือก การทำซ้ำ และการแปลงผลลัพธ์ สามารถประกอบตัวแยกวิเคราะห์ขนาดเล็กให้เป็นตัวแยกวิเคราะห์ขนาดใหญ่ได้
  • โครงสร้างเดียวกันนี้ใช้ได้ในระดับชนิดข้อมูล

ถัดไป: การแยกสตริงในระบบชนิดข้อมูล

เริ่มต้นได้ฟรี

เรียนรู้ TypeScript ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
101
บทเรียน
352

คำถามที่พบบ่อย

บทเรียน “แนวคิดตัวประกอบการแยกวิเคราะห์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “แนวคิดตัวประกอบการแยกวิเคราะห์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “แนวคิดตัวประกอบการแยกวิเคราะห์”

ประกอบตัวแยกวิเคราะห์ขนาดเล็กให้เป็นตัวแยกวิเคราะห์ที่ใหญ่ขึ้น คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “แนวคิดตัวประกอบการแยกวิเคราะห์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนวคิดตัวประกอบการแยกวิเคราะห์
  2. การแยกสตริงระดับชนิดข้อมูล
  3. การแยกวิเคราะห์ด้วยสตริงแบบแม่แบบ
  4. ตัวแยกวิเคราะห์เส้นทางระดับชนิดข้อมูลฉบับย่อ
← กลับไปที่ TypeScript Academy