มีโปรแกรมที่สามารถ 'แปล' ซอร์สโค้ดระหว่างสองภาษาหรือไม่?


28

มีโปรแกรมที่สามารถ 'แปล' ซอร์สโค้ดระหว่างสองภาษาใด ๆ (สมมติว่าผู้แปลมีสิทธิ์เข้าถึงไลบรารี่ที่จำเป็น) หรือไม่?

ถ้ามีพวกเขาทำงานอย่างไร (เทคนิคที่ใช้ความรู้ที่จำเป็น ฯลฯ )? พวกเขาจะสร้างได้อย่างไร?

หากไม่เป็นเช่นนั้นข้อ จำกัด อะไรที่ขัดขวางการพัฒนาของพวกเขา นี่เป็นปัญหาที่สมบูรณ์แบบของ AI หรือไม่ (การแปลภาษาธรรมชาติแสดงเป็นรายการเดียว) หรือไม่

คาดว่าการแปลง EDITจะเกิดขึ้นก็ต่อเมื่อภาษานั้นมีความสามารถในการแสดงออกเท่ากันสามารถแก้ไขปัญหาประเภทเดียวกันได้และรหัสที่จะทำการแปลงสามารถแสดงเป็นภาษาปลายทางได้ (เช่นการแปลงจากเชลล์สคริปต์เป็น MATLAB ไม่เป็นที่คาดหมาย)



14
คุณหมายถึงอะไร "สองภาษา" แน่นอนว่ามีโปรแกรมที่สามารถแปลจากภาษาหนึ่งเป็นอีกภาษาหนึ่งได้ พวกเขาถูกเรียกว่า "คอมไพเลอร์" นั่นคือนิยามของตัวแปลภาษา: โปรแกรมที่แปลโปรแกรมจากภาษาหนึ่งเป็นอีกภาษาหนึ่ง แต่ "มีสองภาษา"? ฉันไม่คิดว่าเป็นไปได้ นักแปลจะต้องรู้ทั้งแหล่งที่มาและภาษาเป้าหมายและโดยทั่วไปจะเป็นภาษาที่เฉพาะเจาะจงสำหรับคู่หนึ่ง ๆ
Jörg W Mittag

โปรแกรมมีให้ในภาษาต้นทางและภาษาเป้าหมาย ฉันกำลังคิดที่จะเขียนโปรแกรมใน C ++ แปลเป็น Java, python, Perl, Ruby, Go ฯลฯ อาจมีข้อ จำกัด บางอย่าง (ฉันไม่คาดหวังให้แปลงเชลล์สคริปต์เป็น MATLAB)
Tobi Alafin

4
ใช่พวกเขาถูกเรียกว่าคอมไพเลอร์พวกเขาทำงานเหมือนคอมไพเลอร์และพวกเขาสามารถสร้างได้เหมือนคอมไพเลอร์
user253751

1
หากโดย "สองภาษาใด ๆ " คุณหมายถึงว่าโปรแกรม (จำกัด ) ควรจะสามารถอ่านและเข้าใจภาษาป้อนข้อมูลได้ไม่ จำกัด จำนวนคำตอบคือไม่สำคัญ แต่จะใช้ชุดที่ จำกัด ของภาษาสำหรับการป้อนและคุณสามารถหาคอมไพเลอร์สำหรับทุกภาษาเหล่านั้น ..
Bakuriu

คำตอบ:


57

TLDR; เป็นไปได้ แต่ไม่สามารถใช้ได้จริง

(สมมติว่านักแปลมีสิทธิ์เข้าถึงไลบรารีที่ต้องมี)

สิ่งนี้กลายเป็นบิตที่ยุ่งยากและเป็นส่วนหนึ่งของสาเหตุที่สิ่งต่าง ๆ เช่นนี้ไม่ได้ถูกใช้ในทางปฏิบัติ

  1. คอมไพเลอร์ทั้งหมดเป็นนักแปล การแปลจากภาษาหนึ่งไปอีกภาษาหนึ่งเป็นไปได้อย่างแน่นอนและนี่คือสิ่งที่คอมไพเลอร์กำลังทำอยู่ ภาษาที่คอมไพเลอร์ถ่มน้ำลายออกมาเป็นผลผลิตโดยทั่วไปรหัสเครื่องหรือประกอบ แต่นี้เป็นเพียงภาษาอื่นและมีคอมไพเลอร์ (บางครั้งเรียก transpilers หรือ transcompilers) ซึ่งแปลระหว่างสองภาษา ตัวอย่างเช่นมีขอบเขตของภาษาที่รวบรวมเพื่อจาวาสคริปต์เช่น PureScript, Elm, ClojureScript ฯลฯ

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

    • การแปลที่แปลงเครื่องทัวริงเป็นรหัสในภาษานี้
    • คำแปลจากภาษานี้เป็นเครื่องทัวริง

    ดังนั้นในการแปลจากภาษา A เป็นภาษา B คุณจะแปลงรหัส A เป็นเครื่องทัวริงจากนั้นแปลงเครื่องนั้นเป็นรหัส B

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

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

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

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

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

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

    แต่โดยทั่วไปแล้วมันไม่ใช่สิ่งที่ใช้งานได้จริง


5
ตัวอย่างหนึ่งสำหรับจุด 4 เป็นasm.js วันนี้ก็เป็นไปได้ที่จะทำให้มันคล้าย ๆสามารถอ่านได้โดยใช้Javascript แหล่งที่มาของแผนที่และตรวจสอบธาตุ แต่ไม่มีใครจะต้องการที่จะทำอย่างนั้น ...
อิสมาเอลมิเกล

1
Modelica เป็นอีกตัวอย่างของภาษาที่ออกแบบมาเพื่อรวบรวมเป็นภาษาอื่น (ในกรณีนี้ C)
Reinstate Monica

เว็บแอสเซมบลีแปลจาก C ++ เป็น javascript
Surt

มีตัวอย่างมากมายของทรานสฟิลเลอร์จาก X ถึง Y แต่มันแตกต่างจากอะไรที่เป็นสากลกับอะไรที่แปล มีกรณีที่เห็นได้ชัดว่าการ transpiling เหมาะสม
jmite

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

2

มีโปรแกรมดังกล่าว ตัวอย่างเช่นนักแปล Lisp-to-Fortran ที่ใช้กันอย่างแพร่หลายในเวลาของพวกเขา Sole Lisp compilers ไม่ได้รวบรวม Lisp โดยตรง แต่สร้าง C code แทนซึ่งจะถูกคอมไพล์โดย C คอมไพเลอร์ปกติ อีกตัวอย่างหนึ่งคือ Vala ที่ไม่ได้รวบรวมโดยตรง แต่แปลเป็น C ++ ก่อนที่จะรวบรวมรหัส C ++ Qt เขียนด้วย MOC เป็นภาษาที่แปลเป็น C ++ เพื่อรวบรวม (แต่เนื่องจาก MOC เป็นเพียง C ++ พร้อมกับคำสั่งเพิ่มเติมสองสามคำที่เราสามารถโต้แย้งได้ว่ามันจะมีชื่อว่า "ภาษาใหม่") - และก่อนหน้านั้น คอมไพเลอร์ C ++ มี C ++ - to-C-translators และบางโปรเจ็กต์ถูกเขียนเป็นภาษาปาสคาลแล้วแปลไปยัง C. เสียงดังกราวและ Java มักจะเป็นสิ่งที่พวกเขาแปล C ++ และรหัส Java เป็นภาษากลางบางอย่างที่สามารถประมวลผลเพิ่มเติมได้

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


0

ไม่ใช่คำตอบโดยตรง แต่มีเครื่องมือเรียกILSpyซึ่งเขียนขึ้นสำหรับ. Net Framework และช่วยให้คุณสามารถคอมไพล์แอสเซมบลี. NET เป็น C # หรือ VB.Net

หากคุณไม่คุ้นเคยกับลักษณะของ. Net คุณสามารถเขียนรหัส. Net ในหลายภาษา แต่โดยหลักแล้วคือ C # หรือ VB.Net เมื่อคอมไพเลอร์รวบรวมแอปพลิเคชันมันจะแปลรหัสเป็นรหัส "Intermediate Language" (หรือ IL สำหรับรหัสย่อ) รหัสนี้จะถูกรวบรวมไปยัง. Net ไบนารี

เนื่องจากแอปพลิเคชัน. Net เป็นไบนารีที่รวบรวมจากรหัส IL, ILSpy สามารถใช้แอปพลิเคชั่น. Net, ย้อนกลับเป็นรหัส IL และจากนั้นให้ใช้ขั้นตอนเดียวต่อไป

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

ฉันรู้ว่านี่ไม่ใช่คอมไพเลอร์ แต่เป็นเครื่องมือที่ให้ผลลัพธ์สุดท้ายใกล้เคียงกับสิ่งที่คุณกำลังมองหาและอันที่จริงฉันใช้มันเพื่อ "แปล" โครงการ VB.Net เป็นสิ่งเล็กน้อย ฉันคุ้นเคยมากขึ้น - C #


0

สำหรับกรณีการใช้งานของคุณ (ตามความคิดเห็น) ดูเหมือนว่าSWIGอาจมีประโยชน์

SWIG เป็นเครื่องมือพัฒนาซอฟต์แวร์ที่เชื่อมต่อโปรแกรมที่เขียนด้วย C และ C ++ กับภาษาการเขียนโปรแกรมระดับสูงที่หลากหลาย SWIG ใช้กับภาษาเป้าหมายประเภทต่างๆรวมถึงภาษาสคริปต์ทั่วไปเช่น Javascript, Perl, PHP, Python, Tcl และ Ruby รายการภาษาที่รองรับยังรวมถึงภาษาที่ไม่ใช่สคริปต์เช่น C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go language, Java รวมถึง Android, Lua, Modula-3, OCAML, Octave, Scilab และ R . รองรับการใช้งาน Scheme, MzScheme / Racket, Chicken)


0

ฉันจำf2c ที่น่าเคารพซึ่งแปลจากแหล่งสู่แหล่งที่มาจาก Fortran 77 เป็น C

มันเป็น (บางครั้งคือ ... ) ส่วนใหญ่ใช้เพื่อแปลรหัสตัวเลขจากทศวรรษที่ผ่านมาโดยไม่ต้องรวมคอมไพเลอร์ Fortran เข้ากับ toolchain


0

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

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