ภาษาที่มีตัวดำเนินการไบนารีสองตัวที่มีความสำคัญเหมือนกันเชื่อมโยงซ้ายและเชื่อมโยงขวา


11

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

(ฉันไม่สามารถหาตัวอย่างได้ แต่ฉันพยายามที่จะเขียนโค้ดตัวแยกวิเคราะห์ทั่วไปพอที่จะจัดการกับกรณีแปลก ๆ นั้น)

จะแยกนิพจน์ของรูปแบบx opl y opr zหรือx opr y opl zได้อย่างไร และโดยทั่วไปกับตัวถูกดำเนินการมากขึ้น?


4
ถ้ามันเจ็บอย่าทำอย่างนั้น
CodesInChaos

1
ใน Haskell คุณสามารถกำหนดโอเปอเรเตอร์ของคุณเองด้วยลำดับความสำคัญของตัวเองและคุณได้รับข้อผิดพลาดในกรณีนี้ ถ้าคุณมีx <@ y @> zกับ<@ถูกทิ้ง-เชื่อมโยงและ@>เป็นขวาเชื่อมโยง GHC ช่วยให้คุณมี "ความเป็นผู้นำข้อผิดพลาดในการแยกวิเคราะห์": "ไม่สามารถผสม ' <@' [infixl 0] และ ' @>' [infixr 0] ในการแสดงออกมัดเดียวกัน" (ที่ผมกำหนดไว้ ตัวดำเนินการเหล่านี้ที่ระดับ 0 เป็นตัวอย่าง)
Antal Spector-Zabusky

@ AntalSpector-Zabusky: นั่นจะเป็นคำตอบที่ยอดเยี่ยม!
Basile Starynkevitch

@ AntalSpector-Zabusky: เหมือนกันใน Swift ฉันคิดว่าคุณสามารถกำหนดโอเปอเรเตอร์ได้ แต่ในนิพจน์คุณต้องใช้ตัวเชื่อมโยงด้านซ้ายทั้งหมดหรือตัวดำเนินการเชื่อมโยงด้านขวาทั้งหมดที่มีลำดับความสำคัญเท่ากัน ดังนั้นคุณสามารถใช้ x leftop y leftop z หรือ x rightop y rightop z แต่ไม่ใช่ x leftop y rightop z
gnasher729

@BasileStarynkevitch: ตามที่คุณต้องการ! เนื่องจากคุณพูดถึง "เครื่องมือแยกวิเคราะห์ที่ยืดหยุ่น" ฉันจึงรวมภาษาอื่น ๆ อีกสองภาษาที่มีตัวแยกวิเคราะห์ที่ยืดหยุ่นมาก (เคยต้องการif_then_else_หรือ[1;2;3]กำหนดไว้ในห้องสมุดหรือไม่)
Antal Spector-Zabusky

คำตอบ:


10

ต่อไปนี้เป็นสามภาษาที่ให้คุณกำหนดผู้ให้บริการของคุณเองซึ่งทำสองสิ่งครึ่งแตกต่างกัน ! Haskell และ Coq ทั้งคู่ไม่อนุญาตประเภทของ shenanigans - แต่ต่างกัน - ในขณะที่ Agda อนุญาตให้มีการผสมกันของความสัมพันธ์แบบนี้


ก่อนอื่นในHaskellคุณไม่ได้รับอนุญาตให้ทำเช่นนี้ คุณสามารถกำหนดผู้ประกอบการของคุณเองและให้ความสำคัญกับพวกเขา (จาก 0–9) และการเชื่อมโยงที่คุณเลือก อย่างไรก็ตามรายงาน Haskell ไม่อนุญาตให้คุณผสมสมาคม :

ตัวดำเนินการที่ไม่ถูกยึดติดติดต่อกันที่มีลำดับความสำคัญเท่ากันต้องเป็นตัวเชื่อมโยงซ้ายหรือขวาเพื่อหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์ [รายงาน Haskell 2010, Ch. 3]

ดังนั้นในGHCหากเรากำหนดinfixlโอเปอเรเตอร์ซ้าย - สัมพันธ์ ( ) <@และโอเปอเรเตอร์ขวา@>ที่ระดับความสำคัญเท่ากัน - สมมุติว่า 0 - แล้วการประเมินx <@ y @> zจะทำให้เกิดข้อผิดพลาด

ข้อผิดพลาดในการแยกวิเคราะห์ลำดับความสำคัญ
    ไม่สามารถผสม ' <@' [ infixl 0] และ ' @>' [ infixr 0] ในนิพจน์มัดเดียวกัน

(อันที่จริงแล้วคุณยังสามารถประกาศโอเปอเรเตอร์ให้เป็นมัด แต่ไม่ใช่แบบเชื่อมโยง==ได้ดังนั้นนั่นx == y == zเป็นข้อผิดพลาดทางไวยากรณ์!)


ในทางกลับกันมีผู้แปลภาษา / ทฤษฎีบทที่พิมพ์ได้อย่างพึ่งพากันAgda (ซึ่งเป็นที่ยอมรับกันว่ามีความสำคัญน้อยกว่า) Agda มีไวยากรณ์ที่อ่อนบางที่สุดของภาษาใด ๆ ที่ฉันรู้จักสนับสนุนตัวดำเนินการmixfix : ไลบรารีมาตรฐานมีฟังก์ชัน

if_then_else_ : ∀ {a} {A : Set a} → Bool → A → A → A

ซึ่งเมื่อมีการเรียกถูกเขียน

if b then t else f

ด้วยข้อโต้แย้งที่กรอกในขีดล่าง! ฉันพูดถึงสิ่งนี้เพราะนี่หมายความว่ามันต้องรองรับการแยกวิเคราะห์ที่ยืดหยุ่นอย่างไม่น่าเชื่อ โดยธรรมชาติแล้ว Agda ยังมีการประกาศ fixity (แม้ว่าระดับความสำคัญของมันจะอยู่เหนือตัวเลขธรรมชาติโดยพลการและอยู่ในช่วง 0-100) และ Agda จะอนุญาตให้คุณผสมตัวดำเนินการที่มีความสำคัญเหมือนกัน แต่ต่างกัน อย่างไรก็ตามฉันไม่สามารถค้นหาข้อมูลเกี่ยวกับสิ่งนี้ได้ในเอกสารดังนั้นฉันจึงต้องทำการทดสอบ

ลองนำมาใช้ใหม่ของเรา<@และ@>จากข้างต้น ในสองกรณีง่าย ๆ เรามี

  • x <@ y @> zแยกเป็นx <@ (y @> z); และ
  • x @> y <@ z(x @> y) <@ zแยกเป็น

ฉันคิดว่าสิ่งที่ Agda ทำคือจัดกลุ่มบรรทัดเป็น "การเชื่อมโยงด้านซ้าย" และ "การเชื่อมโยงทางด้านขวา" และ - ถ้าฉันกำลังคิดเกี่ยวกับสิ่งผิดปกติ - การเชื่อมโยงกลุ่มด้านขวาได้รับ "ลำดับความสำคัญ" นั่นทำให้เรา

a <@ b <@ c @> d @> e @> f <@ g

การแยกเป็น

(((a <@ b) <@ (c @> (d @> (e @> f)))) <@ g

หรือ

แยกวิเคราะห์ต้นไม้ของ <code> (((a <@ b) <@ (c @> (d </code> @> (e @> f)))) <@ g

อย่างไรก็ตามแม้จะมีการทดลองของฉันฉันเดาผิดครั้งแรกที่ฉันเขียนออกมาซึ่งอาจเป็นคำแนะนำ :-)

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


ในที่สุดก็มีCoqภาษาที่ใช้ทฤษฎีบท / ผู้พึ่งพาอาศัยซึ่งมีไวยากรณ์ที่ยืดหยุ่นมากกว่า Agda เนื่องจากส่วนขยายไวยากรณ์นั้นถูกนำไปใช้จริงโดยการให้ข้อกำหนดสำหรับโครงสร้างไวยากรณ์ใหม่แล้วเขียนใหม่เป็นภาษาแกนกลาง ฉันคิดว่า) ใน Coq ไวยากรณ์ของรายการ[1; 2; 3]เป็นการอิมพอร์ตทางเลือกจากไลบรารีมาตรฐาน ไวยากรณ์ใหม่สามารถผูกตัวแปรได้!

อีกครั้งใน Coq เราสามารถกำหนดตัวดำเนินการมัดของเราเองและกำหนดระดับความสำคัญ (ตั้งแต่ 0–99 ส่วนใหญ่) และการเชื่อมโยง อย่างไรก็ตามใน Coq แต่ละระดับความสำคัญจะมีหนึ่งการเชื่อมโยงเท่านั้น ดังนั้นถ้าเรานิยาม<@ว่าเป็นความสัมพันธ์ด้านซ้ายแล้วลองนิยาม@>ความสัมพันธ์ด้านขวาในระดับเดียวกัน - พูดว่า 50 - เราจะได้

ข้อผิดพลาด: ระดับ 50 ได้รับการประกาศว่าเชื่อมโยงกันแล้วขณะนี้คาดว่าจะมีการเชื่อมโยงที่ถูกต้อง

ตัวดำเนินการส่วนใหญ่ใน Coq อยู่ในระดับที่หารด้วย 10 หากฉันมีปัญหาการเชื่อมโยง (การเชื่อมโยงระดับเหล่านี้เป็นระดับโลก) ฉันมักจะชนระดับโดยหนึ่งในทิศทางใดทิศทางหนึ่ง (มักจะขึ้น)


2
(Gee, การเลือกภาษาแปลก ๆ คุณบอกได้ไหมว่าฉันเรียนทฤษฎีการเขียนโปรแกรมภาษา :-P)
Antal Spector-Zabusky

ขอบคุณมากสำหรับคำตอบโดยละเอียดของคุณ BTW คุณวาดภาพได้อย่างไร (ด้วยเครื่องมืออะไรgraphviz?)
Basile Starynkevitch

BTW ทำไม "fixity" แทนที่จะเป็น "ลำดับความสำคัญ"
Basile Starynkevitch

@BasileStarynkevitch: ขึ้นอยู่กับว่าคุณหมายถึงอะไร ถ้าคุณหมายถึงในส่วน Coq ว่าเป็นเพียงความผิดพลาด :-) (และหนึ่งที่คงที่ในขณะนี้!)
Antal สเปคเตอร์-Zabusky

1
@BasileStarynkevitch: ยังฉันพลาดคำถามของคุณเกี่ยวกับภาพ! ฉันวาดด้วยแพ็คเกจ LaTeX qtreeและแสดงมันในLaTeXitซึ่งเป็นตัวแสดงตัวอย่างโค้ด LaTeX สำหรับ Mac \ttfamily \Tree[.<@ [.<@ [.<@ a b ] [.@> c [.@> d [.@> e f ]]]] g ]รหัสที่มาเกี่ยวข้องเป็น
Antal Spector-Zabusky

2

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

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

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