0Pricing
Lua Academy · บทเรียน

ตัวแยกวิเคราะห์นิพจน์อย่างง่าย

สร้างตัวแยกวิเคราะห์แบบเรียกลงลึกสำหรับนิพจน์เลขคณิตด้วย Lua ล้วน

ตัวแยกวิเคราะห์นิพจน์อย่างง่าย เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

เป้าหมาย: แยกวิเคราะห์นิพจน์เลขคณิต

สร้างตัวแยกวิเคราะห์แบบเรียกซ้ำใน Lua ล้วน ๆ เพื่อแยกวิเคราะห์และประเมินนิพจน์อย่าง 3 + 4 * (2 - 1) โดยคำนึงถึงลำดับความสำคัญของตัวดำเนินการ

ตัวแยกโทเค็น

ขั้นแรก แยกข้อมูลเข้าออกเป็นตัวเลข ตัวดำเนินการ และวงเล็บ

local function tokenize(expr)
  local tokens = {}
  for tok in expr:gmatch("[%d%.]+|[%+%-%*/%(%)%^]|%S") do
    tokens[#tokens+1] = tok
  end
  return tokens
end

ตัวแยกโทเค็นที่ปรับปรุงแล้ว

ตัวแยกโทเค็นที่มีความทนทานมากขึ้นโดยใช้รูปแบบ gmatch

local function tokenize(expr)
  local tokens = {}
  for tok in expr:gmatch("%d+%.?%d*|[%+%-%*/%(%)%^]") do
    tokens[#tokens+1] = tok
  end
  return tokens
end

สถานะของตัวแยกวิเคราะห์

ตัวแยกวิเคราะห์จะเก็บรายการโทเค็นและตำแหน่งไว้ ฟังก์ชันตัวช่วย peek และ consume จะเลื่อนไปตามโทเค็น

local function newParser(tokens)
  local pos = 1
  local function peek() return tokens[pos] end
  local function consume() pos = pos + 1; return tokens[pos-1] end
  return {peek=peek, consume=consume}
end

ไวยากรณ์สำหรับนิพจน์

ไวยากรณ์จะคำนึงถึงลำดับความสำคัญ:

  • expr = term ((+ | -) term)*
  • term = factor ((* | /) factor)*
  • factor = number | (expr) | -factor

การแยกวิเคราะห์พจน์

แยกวิเคราะห์นิพจน์การบวกและการลบโดยแยกวิเคราะห์พจน์ แล้วรวมค่า +/- จากซ้ายไปขวา

local parseExpr, parseTerm, parseFactor
parseExpr = function(p)
  local val = parseTerm(p)
  while p.peek() == "+" or p.peek() == "-" do
    local op = p.consume()
    local right = parseTerm(p)
    if op == "+" then val = val + right
    else val = val - right end
  end
  return val
end

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

แยกวิเคราะห์นิพจน์การคูณ รวมถึงการยกกำลัง

parseTerm = function(p)
  local val = parseFactor(p)
  while p.peek() == "*" or p.peek() == "/" do
    local op = p.consume()
    local right = parseFactor(p)
    if op == "*" then val = val * right
    else val = val / right end
  end
  return val
end

การแยกวิเคราะห์ตัวเลขและวงเล็บ

แยกวิเคราะห์องค์ประกอบพื้นฐาน ได้แก่ ค่าลิเทอรัล นิพจน์ย่อยในวงเล็บ และการทำให้เป็นค่าลบแบบเอกภาค

parseFactor = function(p)
  local tok = p.peek()
  if tok == "(" then
    p.consume()  -- (
    local val = parseExpr(p)
    p.consume()  -- )
    return val
  elseif tok == "-" then
    p.consume()
    return -parseFactor(p)
  else
    return tonumber(p.consume())
  end
end

ประกอบทุกส่วนเข้าด้วยกัน

แยกโทเค็น แยกวิเคราะห์ และประเมินนิพจน์

local function eval(expr)
  local tokens = tokenize(expr)
  local parser = newParser(tokens)
  return parseExpr(parser)
end
print(eval("3 + 4 * 2"))      -- 11
print(eval("(3 + 4) * 2"))    -- 14
print(eval("2 ^ 10"))         -- 1024 (if ^ is supported)

การขยายตัวแยกวิเคราะห์

เพิ่มตัวแปร ฟังก์ชัน ตัวดำเนินการเปรียบเทียบ และค่าลิเทอรัลสตริง โดยขยายไวยากรณ์และเพิ่มกรณีใหม่ให้กับ parseFactor

การรายงานข้อผิดพลาด

ติดตามบรรทัดและคอลัมน์ในตัวแยกโทเค็น ทำให้เกิดข้อผิดพลาดที่มีความหมาย เช่น "Expected ')' at position 7, got '+'".

ตัวสร้างตัวแยกวิเคราะห์

สำหรับไวยากรณ์ที่ซับซ้อน ให้ใช้ตัวสร้างตัวแยกวิเคราะห์อย่าง LPEG (ไวยากรณ์นิพจน์สำหรับการแยกวิเคราะห์) LPEG มีพลังและแสดงความหมายได้มากกว่าการเขียนตัวแยกวิเคราะห์แบบเรียกซ้ำด้วยตนเองสำหรับไวยากรณ์ขนาดใหญ่

คำถามเกี่ยวกับตัวแยกวิเคราะห์

ตัวแยกวิเคราะห์แบบเรียกซ้ำใช้สิ่งใดเพื่อบังคับใช้ลำดับความสำคัญของตัวดำเนินการ

ทบทวน: ตัวแยกวิเคราะห์นิพจน์อย่างง่าย

ตัวแยกวิเคราะห์แบบเรียกซ้ำใช้หนึ่งฟังก์ชันต่อหนึ่งกฎไวยากรณ์ จึงบังคับใช้ลำดับความสำคัญของตัวดำเนินการตามธรรมชาติผ่านลำดับชั้นการเรียก เริ่มจากแยกโทเค็นก่อน then จึงสร้างฟังก์ชัน expr → term → factor เพิ่มตัวแปรและฟังก์ชันเพื่อให้ได้ภาษานิพจน์ที่สมบูรณ์

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

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

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

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

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

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

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

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

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

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

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

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

  1. หลักการออกแบบ DSL ใน Lua
  2. โอเวอร์โหลดตัวดำเนินการเพื่อการใช้ DSL อย่างคล่องแคล่ว
  3. การสร้าง DSL สำหรับการกำหนดค่า
  4. ตัวแยกวิเคราะห์นิพจน์อย่างง่าย
← กลับไปที่ Lua Academy