มีภาษาการเขียนโปรแกรมที่ปรับเปลี่ยนได้ส่วนบุคคลที่คุณสามารถใช้ในการแปลงให้เป็นผู้อื่นได้หรือไม่?


13

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

ตัวอย่างเช่นคุณจะเลือกการกำหนดค่าเฉพาะเช่น "บล็อกที่จัดทำดัชนีของ Python" [a,b,c]เริ่มต้นอาร์เรย์^สำหรับการยกกำลังและอื่น ๆ สคริปต์จะแปลงเป็นภาษาที่คุณเลือก


1
ฉันหวังว่าจะไม่ TIMTOWTDI นั้นมีเนื้อหาไม่ดี แต่ "คิดค้นวิธีที่เข้ากันไม่ได้หลายวิธีตามที่คุณต้องการ" จะมีข้อเสียร้อยเท่ากันและมีประโยชน์น้อยกว่า DSLs บางครั้งก็คุ้มค่า แต่ redefining ครึ่งหนึ่งของไวยากรณ์ (หรือเลว - แลกเปลี่ยนสองผู้ประกอบการให้ compability เห็นได้ชัด แต่ความหมายแตกต่างกัน) เพียงสำหรับ heck ของมัน ...

ฉันถามสิ่งนี้เพราะ specifialy ฉันกำลังเขียนโปรแกรมบน javascript และต้องการที่จะสามารถตั้งค่าน้ำตาลในไวยากรณ์ของฉันได้เล็กน้อย แต่ภาษาก็ไม่อนุญาต ไม่แม้แต่ผู้ประกอบการมากไปเป็นไปได้
Dokkat

2
การศึกษาระดับปริญญาบางสิ่งที่คุณอธิบายเสียงเหมือนแมโคร preprocessor ตอนนี้ถ้าเพียง แต่เราอาจจะมีคุณสมบัติที่คล้ายกันสำหรับ Perl ...
Yannis

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

3
"ภาษาโปรแกรมส่วนบุคคล" เหล่านี้มักจะเรียกว่า "ภาษาเฉพาะโดเมน" หรือ DSL
Michael Dillon

คำตอบ:


14

ใช่ แต่อาจไม่ใช่ในแบบที่คุณคิด

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


8
ฉันอย่างใดรู้ Perl จะเป็น (ส่วนหนึ่งของ) คำตอบ ฉันเดามาโครตัวประมวลผลล่วงหน้า C ยังพอดีกับคำอธิบายเพื่อขยายขนาดเล็ก
yannis

ผู้ประกอบการมากไปใน C ++ ก็สามารถทำได้เช่นกัน ตัวอย่างโลกสวัสดีมาถึงใจ ศาล << "สวัสดี";
ลอร์ด Tydus

@LordTydus: แน่นอนและแม้กระทั่งเพียงแค่การใช้งานเกินพิกัดช่วยให้คุณทำเวทย์มนตร์เล็กน้อยหลังอินเตอร์เฟซที่มีสติ มันจะดีถ้า C ++ มีความสามารถในการโอเวอร์โหลดทั่วไปพูดการโหลดมากเกินไปoperator[]สำหรับหลาย ๆ อาร์กิวเมนต์หรือแนะนำตัวดำเนินการใหม่ใน Haskell แต่ฉันสงสัยว่าคณะกรรมการจะเห็นปัญหาการแยกวิเคราะห์ในอดีต
Jon Purdy

3

เสียงเหมือนการเขียนโปรแกรมแนวคิด

ฉันไม่คุ้นเคย แต่XLเป็นภาษาที่ออกแบบมาโดยเฉพาะสำหรับมัน

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

Lisp และ Forth ยังรองรับการเขียนโปรแกรมแนวคิดแม้ว่าน้อยกว่า XL ฉันแนะนำ Lisp เพราะมันใช้งานได้จริงและมีประสิทธิภาพ สิ่งที่สำคัญที่สุดคือไวยากรณ์ที่ชัดเจนและยืดหยุ่นไม่ใช่สัญกรณ์ที่ Lisp จัดให้


ตัวอย่างเช่นคุณจะเลือกการกำหนดค่าเฉพาะเช่น "บล็อกที่มีการจัดทำดัชนีของ Python", "[a, b, c]" เริ่มต้นอาร์เรย์ "^" สำหรับการยกกำลังและอื่น ๆ

คุณอาจสนใจในภาษาเช่น Haskell ซึ่งมีไวยากรณ์ที่ยืดหยุ่นและสม่ำเสมอ


นี่คือสิ่งที่ฉันกำลังมองหา
Dokkat

2

ไม่ใช่ความรู้ของฉัน

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

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

เป็นผลให้ Lisps มีแนวโน้มที่จะได้รับความนิยมโดยเฉพาะอย่างยิ่งสำหรับการใช้ DSL ตัวอย่างที่ดีคือDSL การเข้าถึงข้อมูลใน Clojure (Korma)ซึ่งดูแลรหัสสำเร็จรูปทั้งหมดที่จำเป็นสำหรับการเข้าถึงฐานข้อมูล


2

Scala มักใช้วิธีนี้เพื่อสร้าง DSLs ภาษาเฉพาะโดเมน

สาเหตุหลักมาจาก Scala ไม่มีโอเปอเรเตอร์และสามารถเรียกใช้เมธอด Scala ได้โดยง่าย ตัวอย่างเช่น

5 เป็นวัตถุจำนวนเต็ม ในการคำนวณ 5 บวก 7 คุณสามารถเขียนได้

val ans = 5.add (7) ยกเว้นว่าวิธีการเติมชื่อจริง "+" ดังนั้นคุณจะเขียน:

val ans = 5. + (7) แต่ใน Scala คุณไม่จำเป็นต้องใส่ "." ในการเรียกใช้เมธอดหรือวงเล็บ "()" ล้อมรอบอาร์กิวเมนต์เพื่อเรียกเมธอด + บนวัตถุ 5 คุณต้องเขียน

val ans = 5 + 7 ซึ่งทำงานได้อย่างสมบูรณ์แบบเนื่องจาก Scala ไม่มีผู้ให้บริการที่จะรบกวนการตั้งชื่อวิธีการอันชาญฉลาดของคุณ ตอนนี้ขยายความคิดนั้นไปที่คลาสและวัตถุของคุณเองรวมถึงความจริงที่ว่าคุณสามารถ "แทนที่" วิธีการเช่น + รวมถึงสร้างวิธีการของคุณเองที่ชื่อ >>> หรือ ::! หรือ @ * @ หรือเพียงแค่ชื่อข้อความธรรมดาเช่น fancify


นี่มันเจ๋งมาก. ฉันจะดูสกาล่า
Dokkat

1

ไม่ควรพูดว่าคุณควรใช้เนื่องจากยังคงเป็นส่วนใหญ่อยู่ในการทดลอง แต่กระบวนทัศน์การเขียนโปรแกรมล่าสุดที่น่าสนใจอย่างหนึ่งคือLanguage Oriented Programming (LOP)

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

Sergey Dmitriev อธิบายในรายละเอียดมากขึ้น

นั่นคืออุดมการณ์ของมัน แต่ในทางปฏิบัติแล้วมันลดลงอย่างมากที่สนับสนุนพฤติกรรมที่คุณต้องการ คุณสามารถ:

  • ขยายภาษาที่มีอยู่
  • เขียนภาษาต่าง ๆ
  • ใช้ 'ภาษาการแปลง' ที่มีอยู่เพื่อแปลงคำหลักที่กำหนดใหม่ของคุณเป็นภาษาฐาน

สภาพแวดล้อมการเขียนโปรแกรมที่ใช้งานมากที่สุดที่ฉันรู้ว่าทำตามกระบวนทัศน์นี้คือระบบการเขียนโปรแกรม Metaฟรี(MPS) โดย JetBrains

จริงๆแล้วมันเริ่มถูกนำมาใช้ในซอฟต์แวร์เชิงพาณิชย์ด้วยเช่นกันดังนั้นบางทีมันอาจเริ่มที่จะออกจากเฟส 'ทดลอง':

  • Realaxyเป็นตัวแก้ไขแอ็คชั่นที่สร้างขึ้นทั้งหมดบน MPS การใช้พลังของ LOP ทำให้สามารถใช้งานได้เช่นการปิดสำหรับ AS3
  • mbeddr Cเป็นภาษา C แบบขยายได้ตาม MPS

1

ภาษาเฉพาะโดเมนนั้นมักใช้ในชุมชน Tcl ตัวอย่างเช่นไม่ใช่เรื่องแปลกที่จะเห็นโปรแกรม Tcl ที่มีทั้ง C และ SQL เป็น DSL ที่ฝังตัว (ผ่านแพ็คเกจ Critcl และ Sqlite) เกี่ยวกับข้อ จำกัด เพียงอย่างเดียวของ DSL ที่ฝังตัวคือมันจะดีกว่ามากหากภาษาที่ฝังไว้นั้นมีความสมดุลของเครื่องมือจัดฟันที่โค้งงอ

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

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


0

AFAIU คุณกำลังมองหาภาษาที่สามารถช่วยคุณในการเขียน DSL ของคุณ (Domain Specific Language) มีผู้สมัครที่ดีมากมาย โดยส่วนตัวแล้วฉันอยากจะแนะนำ Ruby หรือ Io เพราะพวกเขามี 1) การใช้งานง่ายเกินไป, 2) การเขียนโปรแกรมเมตาและ 3) กลไกทางเลือกเช่นmethod_missingคุณสามารถใช้เพื่อสร้าง API ของคุณเอง ตัวอย่างเช่นลองดูในsqldslซึ่งเป็น DSL ที่เขียนใน Ruby ซึ่งสร้าง SQL โดยการอ่านโค้ด Ruby


0

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

ดูเหมือนว่าจะมีไวยากรณ์สำหรับ Javascript แต่ไม่เคยใช้มันมาก่อนฉันไม่แน่ใจว่าจะช่วยคุณได้อย่างไร


0

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


นี่คือลิงก์บางส่วน: เนื้อหา PPWIZARD (เอกสารอย่างเป็นทางการ), PPWizard - EDM2 (การอ้างอิงภายนอก) เครื่องมือมีประสิทธิภาพ แต่เอกสารประกอบไม่ใช่เรื่องง่ายที่จะอ่าน (อาจเป็นเพราะพลังของมัน)
Wolf

0

อาจเป็นสิ่งที่คุณกำลังมองหาเป็นคอมไพเลอร์คอมไพเลอร์ คอมไพเลอร์คอมไพเลอร์ใช้คำนิยามภาษาที่เขียนในภาษาที่เป็นทางการและสร้างคอมไพเลอร์สำหรับภาษานี้

ดูที่http://en.wikipedia.org/wiki/Compiler-compiler


0

วิธีหนึ่งที่พบได้ทั่วไปในการทำให้ภาษาโปรแกรมเป็นบางส่วนคือใช้มาโครตัวประมวลผลล่วงหน้า ตัวอย่างเช่นคุณสามารถเรียกใช้ "dokkat-lang" แม้ว่าตัวประมวลผลล่วงหน้า C ก่อนที่จะใส่ผลลัพธ์ที่สภาพแวดล้อม javascript บางอย่างจะดาวน์โหลด

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

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