การแปลงไวยากรณ์นิพจน์ทางคณิตศาสตร์


9

ในบทความการแยกวิเคราะห์นิพจน์โดย Recursive Descent โดย Theodore Norvell (1999)ผู้เขียนเริ่มต้นด้วยไวยากรณ์ต่อไปนี้สำหรับนิพจน์ทางคณิตศาสตร์:

E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v

ซึ่งค่อนข้างแย่เพราะมันคลุมเครือและซ้ำซาก ดังนั้นเขาจึงเริ่มต้นจากการลบการเรียกซ้ำซากด้านซ้ายออกจากผลลัพธ์นั้นเป็นดังนี้:

E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"

แต่ฉันไม่สามารถเข้าใจได้ว่าเขาไปถึงผลลัพธ์นี้ได้อย่างไร เมื่อฉันพยายามลบการสอบถามซ้ำทางซ้ายด้วยตนเองฉันกำลังทำตามวิธีต่อไปนี้:

  1. Firs ฉันจัดกลุ่มการผลิตที่ไม่เหลือการเรียกซ้ำในกลุ่มเดียวและอื่น ๆ (จากซ้ายซ้ำ) ในกลุ่มอื่น:

    E --> E "+" E | E "-" E | E "*" E | E "/" E | E "^" E     // L-recursive
    E --> v | "(" E ")" | "-" E
  2. ต่อไปฉันตั้งชื่อพวกเขาและปัจจัยเพื่อการจัดการที่ง่ายขึ้น:

    E --> E B E  // L-recursive; B stands for "Binary operator"
    E --> P  // not L-recursive; P stands for "Primary Expression"
    P --> v | "(" E ")" | U E   // U stands for "Unary operator"
    B --> "+" | "-" | "*" | "/" | "^"
    P --> "-"

    ตอนนี้ฉันต้องจัดการกับสองโปรดักชั่นแรกซึ่งตอนนี้ง่ายต่อการจัดการ

  3. ฉันเขียนใหม่สองโปรดักชั่นโดยเริ่มจากการผลิตที่ไม่ใช่ L-recursive (ซึ่งก็คือPนิพจน์หลัก) และตามด้วย Tail ทางเลือกTซึ่งฉันกำหนดให้เป็นส่วนที่เหลือของการผลิตดั้งเดิมน้อยกว่า nonterminal ซ้ายซ้ำแรก (นั่นคือเพียงB E) ตามด้วยหางT, หรือซึ่งอาจจะเป็นที่ว่างเปล่า

    E --> P T
    T --> B E T |

    (สังเกตทางเลือกที่ว่างสำหรับหาง)

  4. การผลิตสองอย่างนี้ฉันสามารถเขียนใหม่ใน EBNF ดังนี้:

    E --> P {B E}

    ซึ่งเกือบจะเป็นสิ่งที่ผู้เขียนได้รับ แต่ฉันมีEแทนที่จะPมีในรูปแบบการทำซ้ำเป็นศูนย์หรือมากกว่า (หาง) โปรดักชั่นอื่น ๆ ที่ฉันได้ค่อนข้างเหมือนที่เขาได้รับ:

    P --> v | "(" E ")" | U E
    B -> "+" | "-" | "*" | "/" | "^"
    U -> "-"

    แต่ที่นี่เกินไปฉันมีEแทนในการผลิตครั้งแรกสำหรับPP

ดังนั้นคำถามของฉันคืออะไรฉันหายไปไหน การแปลงพีชคณิตในไวยากรณ์ที่ฉันต้องดำเนินการในตอนนี้เพื่อให้ได้รูปแบบที่แน่นอนเหมือนกับที่ autor ได้รับ ฉันลองใช้การแทนที่Eแต่มันนำพาฉันไปสู่ลูปเท่านั้น ฉันสงสัยว่าฉันต้องการอย่างใดที่จะทดแทนPสำหรับEแต่ผมไม่ทราบว่าการเปลี่ยนแปลงทางกฎหมายใด ๆ ที่จะปรับมัน คุณอาจจะรู้ว่าขั้นตอนที่ขาดหายไปสุดท้ายคืออะไร


โปรดพิจารณาใช้ LaTeX สำหรับการจัดรูปแบบ ดูที่นี่สำหรับไพรเมอร์ (ดูที่นี่สำหรับการสนทนาเกี่ยวกับความเหมาะสมของ LaTeX ในกรณีนี้)
Raphael

คำตอบ:


8

ขั้นตอนที่ขาดหายไป:

E --> P T
T --> B E T |

เขียน E อีกครั้งใน T:

E --> P T
T --> B P T T | 

ลดความซับซ้อนของ T:

E --> P T
T --> B P T | 

เทียบเท่ากับ:

E --> P T
T --> {B P}

และที่นั่นคุณ


1
ขอบคุณสำหรับคำตอบที่ดี :-) ตอนนี้ฉันเห็นสิ่งที่ฉันพลาด: ฉันแทนที่มันด้วยวิธีอื่น ๆ และนั่นคือปัญหา แต่ฉันก็ยังไม่เข้าใจชิ้นเล็กชิ้นน้อย: คุณจะรู้ได้อย่างไรว่าคุณสามารถผสานTมันเข้าด้วยกันเป็นหนึ่งเดียวได้อย่างปลอดภัยT? มีกฎอะไรบ้างไหม? (ฉันสงสัยว่ามันอาจคล้ายกับกฎในตรรกะพีชคณิตแบบบูลที่ระบุว่า "aa = a")
SasQ

BTW ทำไมโพสต์นี้ถูกย้ายที่นี่จาก cstheory.sx และต่างกันอย่างไร ฉันต้องการทราบเพื่อหลีกเลี่ยงข้อผิดพลาดในอนาคต
SasQ

2
@SasQ CSTheory สำหรับคำถามระดับการวิจัยในวิทยาการคอมพิวเตอร์เชิงทฤษฎีเท่านั้นดูคำถามที่พบบ่อยของ CSTheory สำหรับรายละเอียด
Juho

1
@SasQ: TxTT|ε สร้าง x* * * * และเช่นนั้น TxT|ε. ทั่วไปมากขึ้นL* * * *L* * * *=L* * * * สำหรับ Lภาษาใดก็ได้ โปรดทราบว่ามีคำที่ว่างเปล่าεด้านขวาเป็นสิ่งสำคัญ สิ่งนี้ไม่ได้เก็บไว้สำหรับแฟรกเมนต์ไวยากรณ์ทั้งหมดเช่นL+L+L+.
กราฟิลส์

@ ราฟาเอล: มันเกี่ยวข้องกับกฎ idempotence *หรือเปล่า? ผมเห็นใน "มังกรหนังสือ" (3.3, p.91) x** = x*ที่ นั่นเป็นกฎเดียวกันกับที่คุณเคยใช้หรือไม่?
SasQ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.