ค้นหาชุดดังต่อไปนี้


14

ความท้าทายด้านล่างกำหนดให้คุณต้องคุ้นเคยกับทฤษฎี parser อย่างเป็นทางการหากคุณไม่ทราบว่าคำถามนี้ถามอะไรเพราะคุณไม่รู้ว่าคำศัพท์หมายถึงไวยากรณ์และบริบทชุดแรก / ชุดติดตามตามที่ครอบคลุมในหลักสูตรมหาวิทยาลัยจำนวนมาก

ฉันสามารถแนะนำหลักสูตรสแตนฟอร์ดนี้โดยเฉพาะเอกสารประกอบคำบรรยาย 08 และ 09 (จากหน้า 7) ฉันได้แยกไฟล์โกงออกมาจากเอกสารประกอบคำบรรยายเหล่านี้แล้ว - ฉันแนะนำให้ทุกคนที่พยายามอ่านข้อท้าทายนี้ผมขอแนะนำให้ทุกคนพยายามที่ท้าทายนี้จะอ่านมัน


เขียนโปรแกรมหรือฟังก์ชั่นที่ให้ไวยากรณ์ที่ไม่มีบริบทพบชุดต่อไปนี้ของ nonterminal ทุกชุด อย่างไม่เป็นทางการชุดติดตามที่ไม่ใช่เทอร์มินัลคือชุดของเทอร์มินัลและ$(หมายถึงจุดสิ้นสุดของอินพุต) ที่คุณสามารถค้นหาเทอร์มินัลนั้นในประโยคที่ถูกต้อง

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

บริบทของไวยากรณ์ฟรีถูกกำหนดในลักษณะที่ง่ายมาก ทุกบรรทัดมีการผลิตรายการเดียว ทุกการผลิตคือรายการสัญลักษณ์คั่นด้วยช่องว่าง เทอร์มินัลคือสตริงของอักขระที่ล้อมรอบด้วยอะโพสโทรฟี (เช่น'**' ) เพื่อความง่ายคุณอาจสมมติว่าเทอร์มินัลไม่มีช่องว่าง แต่มันจะดีถ้าโปรแกรมของคุณอนุญาต nonterminal อาจจะเป็นสตริงใด ๆ $ที่ไม่มีช่องว่างหรือ การผลิตที่ว่างเปล่า (ปกติระบุด้วยε) เป็นเพียงบรรทัดที่มีเฉพาะที่ไม่ใช่ด้านซ้ายมือ บรรทัดแรกคือการผลิตที่กำหนดสัญลักษณ์เริ่มต้น

เป็นตัวอย่างไวยากรณ์ต่อไปนี้:

S → aSa | bSb | ε

จะได้รับเป็น:

S 'a' S 'a'
S 'b' S 'b'
S

ตัวอย่างอินพุต / เอาต์พุต:

In:
S 'a' S 'a'
S 'b' S 'b'
S

Out:
S {'a', 'b', $}

In:
S A B C
A 'a'
A C 'b'
A
B C
B 'd' A
B
C 'e'
C 'f' 

Out:
S {$}
A {'d', 'e', 'f'}
B {'e', 'f'}
C {'b', 'e', 'f', $}

In:
Start Alice Bob
Alice Charlie 'a'
Alice
Bob Bob 'a' Alice Charlie
Bob '!!!'
Charlie 'b'
Charlie

Out:
Start {$}
Alice {'a', '!!!', 'b', $}
Bob {'a', $}
Charlie {'a', $}

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


4
สมมติว่าผู้คนรู้ว่าไวยากรณ์บริบทฟรีดูเหมือนจะดี แต่ฉันคิดว่ามันจะไม่กระทบกับความท้าทายหากคุณรวมคำจำกัดความของชุดติดตามที่นี่แทนที่จะเชื่อมโยงกับมัน
Martin Ender

1
สิ่งนี้นำความทรงจำบางส่วนกลับมาจาก "การก่อสร้างคอมไพเลอร์ " ที่มหาวิทยาลัยซึ่งเราต้องแก้ไขงานที่คล้ายกันมากมาย
insertusernamehere

คำตอบ:


3

Perl, 257 ไบต์

รวมถึง +4 สำหรับ -0p

กำหนดไวยากรณ์ให้กับ STDIN (โดยไม่มีช่องว่างต่อท้ายตรวจสอบให้แน่ใจว่าได้ลบช่องว่างเพิ่มเติมในตัวอย่างที่สอง) _ถือว่าไม่ใช่ชื่อขั้วเท่านั้นประกอบด้วยตัวอักษรตัวเลขและ ใช้#แทน$เพื่อระบุจุดสิ้นสุดของอินพุต สามารถจัดการกับตัวอักษรที่มีช่องว่าง

perl -M5.010 follow.pl
E T e
e '+' T e
e
T F t
t '*' F t
t
F '(' E ')'
F 'id'
^D

ส่งออกชุดติดตามเป็นรายการnon-terminal literalในลำดับใดไม่มี สำหรับตัวอย่างข้างต้นจะแสดงผล:

F ')'
F #
t ')'
t #
T ')'
T #
F '+'
t '+'
T '+'
F '*'
e ')'
e #
E ')'
E #

follow.pl:

#!/usr/bin/perl -0n
s/'.*?'/~$&/eg;s% (?=(\w.*\n))%$_.=">$1"%reg;/\s/;$_.=">$` #\n";s%^((\w+)\K ?\S*).*%$s{$1}++||"\$a.=s/ $2\\b/$&/rg"%eemgr,s%^(\w+ ).*?(\w+)$%"\$a.=s/>$1/>$2 /rg"%eermg,$_.=$a,s%>.*\xd8\K .*%%g,s%.+\n%$&x!/\n$&/g%eg until$$_++;s/\xd8.*?\xd8/~$&/eg;say/>(\w+ \W\S*\n)/g

ทำงานตามที่แสดง แต่แทนที่\xd8และ\nด้วยเวอร์ชันตามตัวอักษรเพื่อรับคะแนนที่อ้างสิทธิ์

มันควรจะเป็นไปได้ที่จะปรับปรุงสิ่งนี้ตั้งแต่การแปลงfirstชุดไปเป็นfollowชุดนั้นในปัจจุบันนั้นค่อนข้างอึดอัดมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.