ทำไมเราไม่เก็บแผนผังไวยากรณ์แทนรหัสต้นฉบับ?


111

เรามีภาษาโปรแกรมมากมาย ทุกภาษามีการแยกวิเคราะห์และตรวจสอบไวยากรณ์ก่อนที่จะแปลเป็นรหัสเพื่อสร้างแผนผังไวยากรณ์นามธรรม (AST)

เรามีต้นไม้ไวยากรณ์นามธรรมนี้ทำไมเราไม่เก็บต้นไม้ไวยากรณ์นี้แทนที่จะเป็นรหัสที่มา (หรือถัดจากซอร์สโค้ด)?

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

อะไรคือข้อดีข้อเสียของวิธีการนี้?


37
เสียงกระเพื่อมเป็นปกติเขียนเป็นต้นไม้ไวยากรณ์นามธรรม มันไม่เหมือนภาษาอัลกอลมากนัก
David Thornley

2
ฉันไม่อยากจะเชื่อเลยว่าดาวิดเป็นเพียงคนเดียวที่พูดถึงว่าโปรแกรม LISP เป็นโครงสร้างไวยากรณ์ที่เป็นนามธรรม
WuHoUnited

3
นอกเหนือจากประเด็นอื่น ๆ : AST ไม่ได้เป็นสิ่งสุดท้าย นอกจากนี้ยังใช้เวลาไม่นานนักในการสร้าง AST จากโค้ด เมื่อฉันรัน StyleCop ในโปรเจ็กต์ ish เล็ก ๆ ของฉัน VS2010 มันรันกฎ AST ที่แตกต่างกันหลายสิบกฎบนโค้ดหลายพันบรรทัดที่เร็วมาก (บางครั้งหนึ่งหรือสองวินาที) นอกจากนี้ยังง่ายต่อการขยาย StyleCop และการเขียนกฎที่กำหนดเอง ฉันสงสัยว่าการแยกวิเคราะห์ซอร์สโค้ดเป็น AST นั้นเป็นที่เข้าใจกันดีและเป็นปัญหาที่ค่อนข้างง่าย มันกำลังเกิดขึ้นกับภาษาที่ดีในตอนแรกและการเพิ่มประสิทธิภาพและห้องสมุดทั้งหมดที่ยากไม่ใช่การแยกวิเคราะห์
งาน

1
การแยกวิเคราะห์รหัสนั้นไม่ใช่เรื่องง่ายที่จะสร้างรหัสสำหรับภาษาอื่น (คุณจะแปลการรวมเข้าด้วยกันโดยนัยของ Prolog เป็น C อย่างไร) สิ่งที่คุณมีส่วนใหญ่คือ AST สำหรับโปรแกรมต้นฉบับ
Ira Baxter

3
ปัญหาการแยกวิเคราะห์เป็นที่เข้าใจกันดีในทางเทคนิค แต่มันไม่ใช่เรื่องง่ายที่จะแยก C หรือ C ++ เพราะมันเป็นภาษาที่น่ารังเกียจ ตัวแยกวิเคราะห์คอมไพเลอร์หลายตัวแยก C หรือ C ++ ถึง AST: เสียงดังกราว, GCC, ... พวกมันไม่ได้มีไว้สำหรับที่จัดเก็บโปรแกรมและ GCC ต้องการที่จะคอมไพเลอร์ไม่ใช่เครื่องมือวิเคราะห์โปรแกรม ชุดเครื่องมือการปรับโครงสร้างซอฟต์แวร์ DMS ของเราแยกวิเคราะห์หลายภาษาของ C และ C ++, สร้าง ASTs, ตารางสัญลักษณ์และเครื่องมือวิเคราะห์โฟลว์ชนิดต่างๆ Pro ที่ยิ่งใหญ่ของวิธีการนี้คือความสามารถในการสร้างเครื่องมือการเปลี่ยนแปลงอัตโนมัติ semanticdesigns.com/Products/DMS/DMSToolkit.html
Ira Baxter

คำตอบ:


72

ช่องว่างและความคิดเห็น

โดยทั่วไปแล้ว AST จะไม่รวมถึงช่องว่างตัวยุติบรรทัดและความคิดเห็น

การจัดรูปแบบที่มีความหมาย

คุณถูกต้องว่าในกรณีส่วนใหญ่นี่เป็นเชิงบวก (กำจัดการจัดรูปแบบสงครามศักดิ์สิทธิ์) มีหลายกรณีที่การจัดรูปแบบของรหัสดั้งเดิมสื่อถึงความหมายบางอย่างเช่นในตัวอักษรสตริงหลายบรรทัดและ "ย่อหน้ารหัส" (การแยกบล็อกของ งบที่มีบรรทัดว่าง)

รหัสที่ไม่สามารถรวบรวมได้

ในขณะที่ตัวแยกวิเคราะห์จำนวนมากมีความยืดหยุ่นสูงต่อการขาดหายไปของไวยากรณ์รหัสที่มีข้อผิดพลาดมักส่งผลให้เกิดโครงสร้างของต้นไม้ที่แปลกประหลาดซึ่งไม่น่าเชื่อและดีจนถึงจุดที่ผู้ใช้ทำการโหลดไฟล์ซ้ำ เคยทำผิดพลาดใน IDE ของคุณและทันใดนั้นไฟล์ทั้งหมดมี "squigglies"? ลองนึกภาพว่าจะโหลดซ้ำในภาษาอื่นได้อย่างไร

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

ไม่มีสองภาษาใดที่เข้ากันได้อย่างสมบูรณ์แบบ

ดังที่คนอื่น ๆ ชี้ให้เห็นไม่มีเกือบสองภาษาที่มีคุณลักษณะที่สมบูรณ์แบบเสมอกัน ฉันคิดว่าใกล้เคียงที่สุดคือ VB และ C # หรือ JavaScript และ CoffeeScript แต่ถึงอย่างนั้น VB ก็มีฟีเจอร์เช่น XML Literals ที่ไม่มีอะไรเทียบเท่าใน C # และการแปลง JavaScript เป็น CoffeeScript อาจทำให้ JavaScript JavaScript เป็นจำนวนมาก

ประสบการณ์ส่วนตัว:

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


9
มีตัวแยกวิเคราะห์ที่จับความคิดเห็นและเค้าโครงใน AST ชุดเครื่องมือการปรับแก้ซอฟต์แวร์ DMS ของเราทำได้ดี มันมีปัญหากับรหัสผิดกฎหมาย มันมีตัวแยกวิเคราะห์ภาษาที่แม่นยำ
Ira Baxter

2
จริงๆแล้วมีเครื่องมือที่แปลง Javascript เป็น CoffeeScriptดังนั้นฉันคิดว่า JavaScript และ CoffeScript สามารถแปลได้โดยไม่ต้องใช้ตัวอักษร Javascript
Peter Olson

ปีเตอร์เครื่องมือที่น่าสนใจฉันไม่รู้ตัว
Kevin McCormick

+1 สำหรับการจัดรูปแบบที่มีความหมายและประสบการณ์ส่วนตัวที่น่าสนใจ - ช่องว่างสีขาวไม่สำคัญสำหรับคำถามและสามารถแสดงความคิดเห็นได้ รหัสที่มีข้อผิดพลาดจะสามารถแก้ไขได้ง่ายกว่าและแน่นอนว่าส่วนหนึ่งของ "คำถามเดียวในการปกครองทั้งหมด" นั้นไม่สามารถเข้าถึงได้
cregox

43

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

แน่นอนว่าเป็นความคิดที่สมเหตุสมผล ไมโครซอฟท์มีโครงการวิจัยในปี 1990 ที่จะทำเกือบตรงนั้น

สถานการณ์หลายอย่างอยู่ในใจ

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

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

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

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


3
ที่จริงแล้วคุณสามารถทำต้นไม้แตกต่างในภาษาที่เป็นอิสระ คุณต้องใช้เครื่องมือแยกวิเคราะห์ภาษาเพื่อสร้างต้นไม้ ดูกลุ่มเครื่องมืออัจฉริยะดิฟเฟอเรนเซอร์ของเราซึ่งเปรียบเทียบ AST สำหรับหลายภาษา พวกเขาทั้งหมดใช้เอ็นจิน diff พื้นฐานเดียวกัน semanticdesigns.com/Products/SmartDifferencer
Ira Baxter

1
ฉันหวังว่าจะได้เห็นรูปแบบของทีมสวยพิมพ์บนโหลดแบบสวย ๆ พิมพ์บนบันทึกใน Visual Studio สักวัน ... หวังมาหลายปี ... ยังไม่มีโชค ...
Roman Starkov

19

คุณสามารถยืนยันว่านี่คือสิ่งที่รหัสไบต์ใน. NET โปรแกรมสะท้อนแสงของ Infact redgate ทำการแปลรหัสไบต์กลับเป็นภาษาการเขียนโปรแกรม. NET

อย่างไรก็ตามมีปัญหา ไวยากรณ์เป็นภาษาเฉพาะในขณะที่มีสิ่งที่คุณสามารถแสดงในภาษาหนึ่งที่ไม่มีการแสดงในภาษาอื่น สิ่งนี้เกิดขึ้นใน. NET กับ C ++ ซึ่งเป็นภาษา. NET เพียงภาษาเดียวเท่านั้นที่สามารถเข้าถึงระดับการเข้าถึงทั้งหมด 7 ระดับ

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


5
เคยลองถอดรหัส MSIL ที่ผลิตโดย F # หรือไม่
SK-logic

12

ฉันชอบความคิดของคุณบางอย่าง แต่คุณประเมินค่ามากเกินไปว่าการแปลภาษาเป็นภาษาง่ายแค่ไหน หากเป็นเรื่องง่ายคุณไม่จำเป็นต้องเก็บ AST เนื่องจากคุณสามารถแยกภาษา X ลงใน AST จากนั้นเปลี่ยนจาก AST เป็นภาษา Y

อย่างไรก็ตามฉันหวังว่าข้อมูลจำเพาะของคอมไพเลอร์จะคิดอีกเล็กน้อยเกี่ยวกับการเปิดเผย AST ผ่าน API บางประเภท สิ่งต่าง ๆ เช่นการเขียนโปรแกรมที่มุ่งเน้นด้านการ refactoring และการวิเคราะห์โปรแกรมแบบคงที่สามารถดำเนินการผ่าน API ดังกล่าวโดยไม่ต้องใช้ความสามารถเหล่านั้นต้องทำซ้ำงานจำนวนมากที่ดำเนินการแล้วโดยนักเขียนคอมไพเลอร์

มันแปลกที่ความถี่ของโครงสร้างข้อมูลของโปรแกรมเมอร์สำหรับการแสดงโปรแกรมเป็นกลุ่มของไฟล์ที่มีสตริง


5
คุณได้ติดตามการพัฒนาโครงการ " Roslyn " ของ Microsoft เพื่อเปิดคอมไพเลอร์ VBc และ C # เป็น API หรือไม่ มีรุ่นตัวอย่างพร้อมใช้งาน
Carson63000

11

ฉันคิดว่าคะแนนเด่นที่สุดคือ:

  • ไม่มีประโยชน์อะไร คุณบอกว่ามันหมายความว่าทุกคนสามารถใช้ภาษาสัตว์เลี้ยงของพวกเขาได้ แต่นั่นไม่เป็นความจริง - การใช้การแทนทรีของไวยากรณ์จะช่วยลดความแตกต่างของการสร้างประโยคเท่านั้น แต่ไม่ใช่ความหมายเชิงอรรถศาสตร์ มันทำงานได้ในระดับหนึ่งสำหรับภาษาที่คล้ายกันมากเช่น VB และ C # หรือ Java และ Scala แต่ยังไม่ถึงจุดนั้น

  • มันเป็นปัญหา คุณได้รับอิสรภาพทางภาษา แต่คุณสูญเสียอิสรภาพในการใช้เครื่องมือ คุณไม่สามารถอ่านและแก้ไขรหัสในโปรแกรมแก้ไขข้อความหรือแม้แต่ IDE ใด ๆ ได้อีกต่อไป - คุณต้องพึ่งพาเครื่องมือเฉพาะที่พูดถึงการเป็นตัวแทน AST ของคุณสำหรับทั้งการอ่านและการแก้ไขรหัส ไม่มีอะไรได้รับที่นี่

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


4
ประโยชน์ที่อาจเกิดขึ้นคือมันสามารถจบการอภิปรายที่ไม่มีที่สิ้นสุดเช่น "แท็บเทียบกับช่องว่าง", "unix vs. windows bracing / indentation", "คำนำหน้า m_ ต่อหน้าสมาชิกหรือไม่" เพราะพวกเขาสามารถเปลี่ยนเป็นตัวเลือก IDE ง่าย ๆ
nikie

1
@nikie True แต่คุณสามารถทำได้โดยใช้การฟอร์แมตเครื่องมือเช่น - astyleหรือ UnniversalIndent ไม่จำเป็นต้องมีรูปแบบไบนารีอาร์เคน
Konrad Rudolph

2
ประโยชน์ที่แท้จริงจะเป็นไปได้ที่จะมีเครื่องมือ diff / patch ที่ให้ความเข้าใจที่ดีขึ้นเกี่ยวกับสิ่งที่เปลี่ยนแปลงไป แต่นั่นดูเหมือนจะต้องการเครื่องมือใหม่ทั้งหมดสำหรับการควบคุมเวอร์ชันซึ่งเป็นข้อ จำกัด ที่ร้ายแรง
Peter Taylor

1
หากคุณคิดว่า "ไม่มีประโยชน์" คุณจะไม่เห็น Workbench โดเมนของซอฟต์แวร์ Intentional
Craig Stuntz

1
โดยสังเขปตรรกะเดียวกันสามารถถูกนำเสนอในรูปแบบที่แตกต่างกันไม่ใช่ข้อความทั้งหมดทำให้กฎสามารถเข้าถึงได้โดยผู้ที่ไม่ใช่โปรแกรมเมอร์ เช่นผู้เชี่ยวชาญโดเมนเช่นนักคณิตศาสตร์ประกันภัยสามารถเขียนส่วนของคณิตศาสตร์ประกันภัยของใบสมัครประกันภัย ชอบ DSL ยกเว้นไม่ได้ จำกัด อยู่ที่การเป็นตัวแทนนั้น แม้ว่ามันจะเกี่ยวข้องกับคำถามมาก มีการสาธิตที่ดี
Craig Stuntz

6

ฉันคิดว่าถ้าคุณเก็บทั้งข้อความและ AST คุณก็ไม่ได้เพิ่มอะไรที่มีประโยชน์เพราะข้อความมีอยู่แล้วในหนึ่งภาษาและ AST สามารถสร้างขึ้นใหม่ได้อย่างรวดเร็วจากข้อความ

ในทางกลับกันถ้าคุณเพียงเก็บ AST คุณจะสูญเสียสิ่งต่าง ๆ เช่นความคิดเห็นที่ไม่สามารถกู้คืนได้


6
และถ้าคุณทำให้ความคิดเห็นเป็นส่วนหนึ่งของต้นไม้ไวยากรณ์ (กับโหนดความคิดเห็นที่สามารถเป็นลูกของอะไรก็ได้)?
วงล้อประหลาด

เครื่องมือของเราทำอย่างนั้น ดูความคิดเห็นอื่นของฉันในหัวข้อนี้
Ira Baxter

4

ฉันเชื่อว่าความคิดนั้นน่าสนใจในทางทฤษฎี แต่ไม่สามารถนำไปใช้ได้จริงเนื่องจากภาษาการเขียนโปรแกรมที่แตกต่างกันสนับสนุนโครงสร้างที่แตกต่างกันบางอย่างที่ไม่มีความเทียบเท่าในภาษาอื่น

ตัวอย่างเช่น X ++ มีคำสั่ง 'ขณะที่เลือก' ซึ่งไม่สามารถเขียนใน C # ได้โดยไม่ต้องมีรหัสพิเศษจำนวนมาก (คลาสเพิ่มเติม, ตรรกะพิเศษ, ฯลฯ ) http://msdn.microsoft.com/en-us/library/aa558063.aspx

สิ่งที่ฉันพูดที่นี่คือหลายภาษามีน้ำตาลประโยคที่แปลในรหัสใหญ่ของภาษาเดียวกันหรือแม้กระทั่งองค์ประกอบที่ไม่มีอยู่ในคนอื่น ๆ นี่คือตัวอย่างว่าทำไมวิธี AST จะไม่ทำงาน:

ภาษา X มีคำสำคัญ K ที่ถูกแปลใน AST ใน 4 ข้อความ: S1, S2, S3 และ S4 AST ได้รับการแปลเป็นภาษา Y และโปรแกรมเมอร์เปลี่ยนแปลง S2 เกิดอะไรขึ้นกับการแปลกลับไปเป็น X รหัสถูกแปลเป็นคำสั่ง 4 รายการแทนที่จะเป็นคำหลักคำเดียว ...

อาร์กิวเมนต์สุดท้ายของวิธี AST คือฟังก์ชันของแพลตฟอร์ม: จะเกิดอะไรขึ้นเมื่อฟังก์ชันฝังอยู่ในแพลตฟอร์ม ชอบ. NET ของ Environment.GetEnvironmentVariable คุณแปลมันได้อย่างไร


4

มีระบบที่สร้างขึ้นรอบ ๆ ความคิดนี้คือ JetBrains MPS ตัวแก้ไขค่อนข้างแปลกหรือแตกต่างกันเล็กน้อย แต่โดยทั่วไปแล้วมันไม่ใช่ปัญหาใหญ่ ปัญหาที่ใหญ่ที่สุดคือดีว่ามันไม่ได้เป็นข้อความใด ๆ เพิ่มเติมดังนั้นคุณจึงไม่สามารถใช้เครื่องมือข้อความตามปกติ - บรรณาธิการอื่น ๆgrep, sed, ผสานและ diff เครื่องมือ ฯลฯ


2
... แต่คุณจะได้รับจำนวนมากของคุณสมบัติแก้ไขออกมาจากกล่อง ลองพิจารณาการขยายคำตอบนี้สักหน่อยมันเป็นเทคโนโลยีที่น่าสนใจมากซึ่งสมควรได้รับรายละเอียดเพิ่มเติมเกี่ยวกับข้อดีของการไม่เก็บซอร์สโค้ดเป็นข้อความ เช่นเป็นฉันตอบในคำถามนี้บนแท็บเทียบกับพื้นที่
Steven Jeuris

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

1
ผู้คนทำผิดพลาดอย่างต่อเนื่อง AST ทำให้มันง่ายกว่าถ้าคุณมีข้อความแบบดิบ แต่สำหรับสิ่งที่น่าสนใจคุณต้องมีข้อมูลเพิ่มเติม: การควบคุมและการไหลของข้อมูลตารางสัญลักษณ์การวิเคราะห์ช่วง ... AST ช่วย แต่เป็นเพียงส่วนเล็ก ๆ ของสิ่งที่จำเป็นจริงๆ
Ira Baxter

@Ira Baxter แน่นอนว่าง่ายกว่าด้วย AST แต่มันยากมากที่จะรวมเข้ากับ โครงสร้างพื้นฐานที่มีอยู่
SK-logic

4

มีผลิตภัณฑ์หลายอย่างที่รู้จักกันทั่วไปว่าเป็น "workbenches ภาษา" ที่เก็บ ASTs และปัจจุบันในบรรณาธิการของพวกเขา "ประมาณการ" ของ AST กลับเป็นภาษาเฉพาะ ดังที่ @ sk-logic กล่าวว่า MPS ของ JetBrains เป็นหนึ่งในระบบดังกล่าว อีกอย่างคือ Intentional Workbench ของซอฟต์แวร์ Intentional

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

ในทางปฏิบัติ workbenches ภาษาได้ช้าในการจับเพราะนอกเหนือจากงาน DSL นักพัฒนาอาจต้องการทำงานในภาษาโปรแกรมทั่วไปที่คุ้นเคย เมื่อเปรียบเทียบแบบตัวต่อตัวกับ text editor หรือ IDE โปรแกรมภาษา workbenches มีค่าใช้จ่ายมากมายและข้อดีของมันยังไม่ชัดเจน ภาษาที่ฉันได้เห็นไม่มีการบีบอัดตัวเองจนถึงจุดที่พวกเขาสามารถขยาย IDEs ของตัวเองได้อย่างง่ายดาย - นั่นคือถ้า workbenches ภาษาที่ดีสำหรับการผลิตทำไมไม่มีเครื่องมือปรับแต่งภาษากลายเป็นดีกว่า - และ - ดีกว่าในอัตราที่เร็วขึ้นและเร็วขึ้น?


"ปรับแต่งภาษา" ไม่ควรจำเป็นต้องขึ้นอยู่กับการจัดเก็บ AST ดิบ พวกเขาสามารถเป็นข้อความเชิงไวยากรณ์ได้เช่นกันดูตัวอย่างmeta-alternative.net/pfront.pdf (และอันนี้จริง ๆ แล้วขยาย Visual Studio และ Emacs แก้ไขด้วย eDSL ใด ๆ ที่นำมาใช้ด้านบนของมัน)
SK-logic

นั่นเป็นกระดาษที่น่าสนใจ มันเตือนฉัน (ในความทะเยอทะยานไม่ใช่ในการนำไปใช้) ของเครื่องมือที่เรียกว่า SugarJ ซึ่งนำเสนอที่ SPLASH / OOPSLA เมื่อไม่กี่สัปดาห์ที่ผ่านมา: uni-marburg.de/fb12/ps/research/sugarj
Larry

น่าสนใจฉันจะลองอันนั้นเช่นกัน
SK-logic

3

คุณได้อ่านใจของฉัน

เมื่อฉันเข้าเรียนหลักสูตรคอมไพเลอร์เมื่อไม่กี่ปีที่ผ่านมาฉันค้นพบว่าถ้าคุณใช้ AST และทำให้เป็นอนุกรมด้วยสัญกรณ์คำนำหน้าแทนที่จะเป็นสัญกรณ์มัดปกติและใช้วงเล็บเพื่อคั่นงบทั้งหมดคุณจะได้ Lisp ในขณะที่ฉันเรียนรู้เกี่ยวกับ Scheme (ภาษาถิ่น Lisp) ในการศึกษาระดับปริญญาตรีของฉันฉันไม่เคยได้รับความชื่นชมจากมัน ฉันได้รับการชื่นชมอย่างแน่นอนสำหรับ Lisp และภาษาถิ่นของมันอันเป็นผลมาจากหลักสูตรนั้น

ปัญหาเกี่ยวกับสิ่งที่คุณเสนอ:

  1. มันยาก / ช้าในการเขียน AST ในสภาพแวดล้อมแบบกราฟิก ท้ายที่สุดพวกเราส่วนใหญ่สามารถพิมพ์ได้เร็วกว่าที่เราสามารถเลื่อนเมาส์ได้ คำถามที่เกิดขึ้นก็คือ "คุณจะเขียนรหัสโปรแกรมด้วยแท็บเล็ตได้อย่างไร" การพิมพ์บนแท็บเล็ตช้า / ยุ่งยากเมื่อเปรียบเทียบกับคีย์บอร์ด / แล็ปท็อปที่มีคีย์บอร์ดฮาร์ดแวร์ หากคุณสามารถสร้าง AST ได้โดยการลากและวางส่วนประกอบจากจานสีลงบนผืนผ้าใบบนการเขียนโปรแกรมอุปกรณ์หน้าจอสัมผัสขนาดใหญ่บนแท็บเล็ตอาจกลายเป็นเรื่องจริง

  2. เครื่องมือที่มีอยู่ของเรามีน้อย / ไม่สนับสนุนสิ่งนี้ เรามีการพัฒนาหลายทศวรรษในการสร้าง IDE ที่ซับซ้อนมากขึ้นและบรรณาธิการที่ชาญฉลาดยิ่งขึ้น เรามีเครื่องมือทั้งหมดเหล่านี้สำหรับการจัดรูปแบบข้อความเปรียบเทียบข้อความค้นหาข้อความ เครื่องมือใดบ้างที่สามารถเทียบเท่ากับการค้นหานิพจน์ทั่วไปในทรีได้ หรือแตกต่างจากต้นไม้สองต้น? ทุกสิ่งเหล่านี้ทำได้อย่างง่ายดายด้วยข้อความ แต่พวกเขาสามารถเปรียบเทียบคำศัพท์เท่านั้น เปลี่ยนชื่อตัวแปรเช่นคำที่แตกต่างกัน แต่ความหมายความหมายเหมือนกันและเครื่องมือ diff เหล่านั้นทำงานเป็นปัญหา เครื่องมือดังกล่าวที่พัฒนาขึ้นเพื่อทำงานบน AST แทนที่จะเป็นข้อความจะช่วยให้คุณใกล้ชิดกับการเปรียบเทียบความหมายทางความหมาย นั่นจะเป็นสิ่งที่ดี

  3. ในขณะที่การแปลงซอร์สโค้ดของโปรแกรมเป็น AST นั้นค่อนข้างเข้าใจได้ดี (เรามีคอมไพเลอร์และล่ามใช่ไหม?) การเปลี่ยน AST เป็นโค้ดโปรแกรมนั้นไม่เข้าใจ การคูณจำนวนเฉพาะสองตัวเพื่อให้ได้จำนวนมากประกอบกันนั้นค่อนข้างตรงไปตรงมา แต่การแยกตัวประกอบจำนวนที่มีขนาดใหญ่กลับเข้าสู่ช่วงเวลานั้นยากกว่ามาก นั่นคือสิ่งที่เราอยู่กับการแยกวิเคราะห์ VS decompiling AST นั่นคือสิ่งที่ความแตกต่างระหว่างภาษากลายเป็นปัญหา แม้ในภาษาใดภาษาหนึ่งมีหลายวิธีในการถอดรหัส AST วนซ้ำผ่านชุดของวัตถุและรับผลลัพธ์บางชนิดเช่น ใช้สำหรับลูปวนซ้ำผ่านอาร์เรย์หรือไม่ นั่นจะกะทัดรัดและรวดเร็ว แต่ก็มีข้อ จำกัด ใช้ Iterator บางชนิด ดำเนินการกับคอลเล็กชันหรือไม่ การสะสมนั้นอาจเป็นขนาดแปรปรวนซึ่งเพิ่มความยืดหยุ่นที่ค่าใช้จ่าย (เป็นไปได้) ของความเร็ว แผนที่ / ลด? มีความซับซ้อนมากขึ้น และสำหรับ Java ขึ้นอยู่กับความชอบของคุณ

ในเวลาความพยายามในการพัฒนาจะถูกใช้และเราจะพัฒนาโดยใช้หน้าจอสัมผัสและ AST การพิมพ์จะกลายเป็นสิ่งจำเป็นน้อยลง ฉันเห็นว่าเป็นความก้าวหน้าเชิงตรรกะจากที่เราอยู่ดูวิธีที่เราใช้คอมพิวเตอร์ในวันนี้นั่นจะแก้ปัญหา # 1

เรากำลังทำงานกับต้นไม้อยู่แล้ว เสียงกระเพื่อมเป็นเพียง ASTs ต่อเนื่อง XML (และ HTML ตามส่วนขยาย) เป็นเพียงแผนผังแบบอนุกรม หากต้องการทำการค้นหาเรามีต้นแบบสองสามอัน ได้แก่ XPath และ CSS (สำหรับ XML และ HTML ตามลำดับ) เมื่อมีการสร้างเครื่องมือกราฟิกที่ช่วยให้เราสามารถสร้างตัวเลือกและตัวดัดแปลงสไตล์ CSS เราจะแก้ไขส่วนที่ 2 เมื่อตัวเลือกเหล่านั้นสามารถขยายได้เพื่อรองรับ regexes เราจะเข้าใกล้มากขึ้น ยังคงมองหาเครื่องมือ diff ดิจิตัลที่ดีสำหรับการเปรียบเทียบเอกสาร XML หรือ HTML สองรายการ เมื่อผู้คนพัฒนาเครื่องมือเหล่านั้น # 2 จะสามารถแก้ไขได้ ผู้คนกำลังทำงานกับสิ่งเหล่านี้อยู่แล้ว พวกเขาไม่ได้อยู่ที่นั่น

วิธีเดียวที่ฉันจะเห็นว่าสามารถถอดรหัส AST เหล่านั้นไปยังข้อความภาษาการเขียนโปรแกรมจะเป็นสิ่งที่แสวงหาเป้าหมาย หากฉันแก้ไขโค้ดที่มีอยู่เป้าหมายอาจทำได้โดยอัลกอริทึมซึ่งทำให้โค้ดที่แก้ไขของฉันใกล้เคียงกับโค้ดเริ่มต้นมากที่สุด (diff ต่างกันเล็กน้อย) หากฉันเขียนโค้ดตั้งแต่เริ่มต้นเป้าหมายอาจเป็นโค้ดที่เล็กที่สุดและแคบที่สุด (น่าจะเป็นลูปสำหรับวน) หรืออาจเป็นรหัสที่ขนานได้อย่างมีประสิทธิภาพมากที่สุด (น่าจะเป็นแผนที่ / ลดหรือสิ่งที่เกี่ยวข้องกับ CSP) ดังนั้น AST เดียวกันอาจส่งผลให้รหัสแตกต่างกันอย่างมีนัยสำคัญแม้ในภาษาเดียวกันขึ้นอยู่กับวิธีการตั้งเป้าหมาย การพัฒนาระบบดังกล่าวจะแก้ปัญหา # 3 มันจะมีความซับซ้อนในการคำนวณซึ่งหมายความว่าเราอาจต้องมีการจัดการเซิร์ฟเวอร์กับลูกค้า


1

หากความตั้งใจของคุณคือกำจัดการอภิปรายเกี่ยวกับการจัดรูปแบบสไตล์บางทีสิ่งที่คุณต้องการคือตัวแก้ไขที่อ่านในไฟล์ต้นฉบับจัดรูปแบบตามความชอบส่วนตัวของคุณสำหรับการแสดงและการแก้ไข แต่เมื่อทำการบันทึก การใช้งาน

มันค่อนข้างจะง่ายถ้าคุณใช้โปรแกรมแก้ไขเช่นEmacs การเปลี่ยนรูปแบบการจัดรูปแบบของไฟล์ทั้งหมดเป็นงานคำสั่งสามงาน

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


1
จากนั้นคุณจะยังคงต้องการ semantic diff และ merge (เช่นอีกครั้งระดับ AST)
SK-logic

ไม่เครื่องมือแก้ไขจะปรับรูปแบบกลับเป็นสไตล์ของทีมเพื่อจัดเก็บแหล่งที่มาดังนั้นคุณจะต้องเปรียบเทียบแหล่งที่มาประเภทหนึ่งกับประเภทเดียวกัน
กุสตาฟเบอร์แทรม

จุดที่ดีการเป็นตัวแทนเพียงหนึ่งเดียวในการแก้ปัญหาทั้งหมด
SK-logic

1
ไม่ได้มันจะแก้ปัญหาเฉพาะปัญหาของการคอมไฟล์สองไฟล์เพื่อระบุตัวตน หากคุณต้องการเห็นความแตกต่างระหว่างไฟล์คุณต้องการสิ่งที่เข้าใจโครงสร้าง ฉันชอบ emacs ของฉัน แต่ไม่เข้าใจโครงสร้าง
Ira Baxter

Emacs นั้นยอดเยี่ยม แต่ฉันไม่เคยใช้มันเพื่อความแตกต่าง หากต้องการ diff tree source ของฉันก่อนเช็คอินฉันจะใช้meldเสมอ จริงๆแล้วมันเข้าใจ SVN และคอมไพล์ สำหรับ Windows ฉันใช้WinMergeร่วมกับเต่า
กุสตาฟ Bertram

1

มันยากที่จะอ่านและแก้ไข AST แทนที่จะเป็นซอร์สโค้ด

อย่างไรก็ตามเครื่องมือคอมไพเลอร์บางตัวเกี่ยวข้องกับการอนุญาตให้ใช้ AST Java bytecode และ. NET Intermediate code ทำงานคล้ายกับ AST


1
มันง่ายกว่าที่จะทำการดัดแปลง AST ด้วยเครื่องมือเชิงกลได้ง่ายกว่าการใช้ข้อความ คุณสามารถทำได้ด้วยการเปลี่ยนแปลงที่นำรูปแบบ ดูsemanticdesigns.com/Products/DMS/ProgramTransformation.html
Ira Baxter

2
บอกเรื่องนี้กับ LISPers ตอนนี้ ...
hugomg

@Ira Baxter ฉันรู้ว่าฉันทำงานจริงกับเครื่องมือแสดงผลที่กำหนดเองซึ่งทำงานโดยตรงกับ AST อย่างไรก็ตามบางครั้งผู้พัฒนาต้องทำงานกับข้อความแทนที่จะเป็นภาพ AST บางตัวแสดงเป็นภาษาการเขียนโปรแกรมที่สั้นกว่าในข้อความ
umlcat

@umlcat คุณช่วยเล่าเพิ่มเติมเกี่ยวกับงานของคุณเกี่ยวกับเครื่องมือแสดงภาพสำหรับ AST ได้หรือไม่?
Daniel Albuschat

@Daniel Albuschat ฉันทำงานโครงการภาษาสัตว์เลี้ยงตัวแยกวิเคราะห์ยากที่จะใช้ดังนั้นฉันข้ามมันไปสักครู่และสร้างเครื่องมือที่ฉันแสดง AST (ฟอร์มที่มีการควบคุม treeview) และเพิ่มการแสดงออกโดยตรง และสามารถทำตรงข้ามสร้างรหัสจาก AST
umlcat

0

มันเป็นความคิดที่ดี แต่ AST ของแต่ละภาษานั้นแตกต่างจากกัน

ข้อยกเว้นเดียวที่ฉันรู้คือสำหรับ VB.NET และ C # ซึ่ง Microsoft ระบุว่าพวกเขาเป็น "ภาษาเดียวกันกับไวยากรณ์ที่แตกต่างกัน" แม้แต่ภาษา. NET อื่น ๆ (IronPython, F #, อะไรก็ตาม) จะแตกต่างกันในระดับ AST

สิ่งเดียวกันกับภาษา JVM พวกเขาตั้งเป้าหมายเป็นไบต์เดียวกัน แต่โครงสร้างภาษาต่างกันทำให้ภาษาต่างกันและ AST ที่แตกต่างกัน

แม้แต่ภาษา 'เลเยอร์บาง' เช่น CoffeScript และ Xtend ก็ใช้ทฤษฎีภาษาพื้นฐานมากมาย (JavaScript และ Java ตามลำดับ) แต่แนะนำแนวคิดระดับที่สูงขึ้นซึ่ง (หรือควร) ไว้ที่ระดับ AST

ถ้า Xtend สามารถสร้างขึ้นใหม่จาก Java AST ฉันคิดว่ามันจะถูกกำหนดเป็น Java-to-Xtend 'uncompiler' ที่สร้าง abstractions ระดับสูงขึ้นอย่างน่าอัศจรรย์จากโค้ด Java ที่มีอยู่คุณไม่คิดเหรอ?


1
ในขณะที่บางคนคุ้นเคยกับคอมไพเลอร์ C # และ VB อย่างใกล้ชิดฉันสามารถบอกคุณได้ว่าพวกเขาเหมือนกันแต่มีรายละเอียดที่สำคัญเพียงพอที่จะแตกต่างกันพอที่จะไม่สามารถปฏิบัติต่อพวกเขาในฐานะ "ภาษาเดียวกันกับไวยากรณ์ที่แตกต่างกัน" เราถือว่าการทำเช่นนั้นสำหรับโครงการ Roslyn; การสร้างคอมไพเลอร์ตัวเดียวที่สามารถรวบรวมทั้งสองภาษาด้วยสิ่งอำนวยความสะดวกที่เท่าเทียมกันและหลังจากการถกเถียงกันมากก็ตัดสินใจที่จะใช้คอมไพเลอร์สองตัวสำหรับสองภาษา
Eric Lippert

@EricLippert: นั่นเป็นความอัปยศ ไม่ใช่ว่าฉันวางแผนที่จะเรียนรู้ทั้งสองภาษา แต่มันฟังดูเป็นข้อยกเว้นที่ดี ฉันคิดว่า htat ทิ้งเสียงกระเพื่อมเหมือนดีแลนและแอลกอลเหมือนดีแลนเป็นเพียง 'ภาษาเดียวกันกับไวยากรณ์ที่แตกต่างกัน' ตัวอย่าง
Javier
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.