aynı önceliğe sahip iki ikili işleç içeren dil, sol ilişkilendirme ve sağ ilişkilendirme


11

İki ikili operatörler sahip herhangi bir programlama (ya betik) dili (veya bazı etki alanı belirli bir dil) var mı oplve oprbir aynı olan önceliğine opl-sol ilişkisel ve varlık oprsağ ilişkisel olmak?

(Böyle bir örnek bulamıyorum, ancak bu garip durumu işlemek için genel olarak bazı ayrıştırıcı kodlamaya çalışıyorum)

X opl y opr z veya x opr y opl z formundaki ifadeler nasıl ayrıştırılır? Ve daha genel olarak daha fazla işlenenle?


4
Acıyorsa, bunu yapma.
CodesInChaos

1
Haskell'de kendi infix operatörlerinizi kendi öncelikleri ile tanımlayabilirsiniz ve bu durumda bir hata alırsınız; Eğer varsa x <@ y @> zile <@olan sol-ilişkisel ve @>sağ ilişkisel olmak GHC size "Öncelik ayrıştırma hatası" veriyor: " 'karştramazsnz <@' [infixl 0] ve ' @>' [infixr 0] Aynı infix ifadede" Ben tanımlanan ( bu işleçler örnek için 0 düzeyinde).
Antal Spector-Zabusky

@ AntalSpector-Zabusky: Bu harika bir cevap olurdu!
Basile Starynkevitch

@ AntalSpector-Zabusky: Swift'te aynı. Bence operatörleri gerçekten tanımlayabilirsiniz, ancak bir ifadede tüm sol çağrışım ya da tüm sağ çağrışım operatörlerini aynı önceliğe sahip olarak kullanmalısınız. Böylece x leftop y leftop z veya x rightop y rightop z kullanabilirsiniz, ancak x leftop y rightop z kullanamazsınız.
16:52

@BasileStarynkevitch: İstediğiniz gibi! "Esnek ayrıştırıcılardan" bahsettiğinizden beri, çok esnek ayrıştırıcılara ( kütüphanelerde hiç tanımlanmış if_then_else_veya [1;2;3]tanımlanmış mı?) Sahip birkaç daha belirsiz dil ekledim .
Antal Spector-Zabusky

Yanıtlar:


10

İşte iki buçuk farklı şey yapan kendi operatörlerinizi tanımlamanıza izin veren üç dil ! Haskell ve Coq her ikisi de bu tür maskaralıklara izin vermiyor - ama farklı olarak - Agda bu tür ilişkilerin karıştırılmasına izin veriyor.


İlk olarak, Haskell'de bunu yapmanıza izin verilmiyor. Kendi operatörlerinizi tanımlayabilir ve onlara önceliklerinizi (0-9 arasında) ve istediğiniz birliği verebilirsiniz. Ancak, Haskell Raporu , ortaklıkları karıştırmanıza izin vermez :

Bir sözdizimi hatasını önlemek için aynı önceliğe sahip art arda saydam olmayan işleçlerin hem sol hem de sağ ilişkilendirici olması gerekir. [Haskell 2010 Raporu, Böl. 3]

Dolayısıyla, GHC'de , aynı öncelik düzeyinde bir sol çağrışım ( infixl) operatörü <@ve sağ çağrışımsal operatör tanımlarsak @>- 0 diyelim - o zaman değerlendirme x <@ y @> zhatayı verir

Öncelik ayrıştırma hatası , aynı infix ifadesinde
    ' <@' [ infixl 0] ve ' @>' [ infixr 0] öğelerini karıştıramaz

(Aslında, bir operatörün bir infix olduğunu, ancak ilişkisel ==olmadığını x == y == z, yani sözdizimi hatası olduğunu bildirebilirsiniz !)


Öte yandan, bağımlı olarak yazılan dil / teorem kanıtlayıcı Agda (kuşkusuz, daha az ana akımdır ) var. Agda, mixfix operatörlerini destekleyen, bildiğim herhangi bir dilin en biçimlendirilebilir sözdiziminin bazılarına sahiptir : standart kütüphane işlevi içerir

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

arandığında yazılan

if b then t else f

alt çizgileri dolduran argümanlar ile! Bundan bahsediyorum çünkü bu inanılmaz esnek ayrıştırmayı desteklemesi gerektiği anlamına geliyor. Doğal olarak, (onun öncelik seviyeleri üzerinde keyfi doğal sayılar değişir ve tipik 0-100 olmasına rağmen) Agda da fixity bildirimleri vardır ve Agda yapar aynı öncelik ancak farklı fixities operatörlerine karıştırmak için izin verir. Bununla birlikte, bu konuda dokümantasyonda bilgi bulamıyorum, bu yüzden denemek zorunda kaldım.

Hadi bizim <@ve @>yukarıdan tekrar kullanalım . İki basit durumda,

  • x <@ y @> zolarak ayrıştırma x <@ (y @> z); ve
  • x @> y <@ zolarak ayrıştırma (x @> y) <@ z.

Ben düşünüyorum Ne Agda yaptığı grup "sol birleştirici" ve "sağ çağrışımlı" parçalar halinde çizgisini ve - Ben yanlış şeyler düşünüyorum sürece - sağ ilişkisel yığın bitişik argümanlar kapma "öncelik" alır. Bu bize

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

olarak ayrıştırma

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

veya

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

Ancak, deneylerime rağmen, ilk kez yazdığımda yanlış olduğunu tahmin ettim, bu da öğretici olabilir :-)

(Ve Agda, Haskell gibi, ayrıştırma hatalarını doğru bir şekilde veren ilişkisel olmayan işleçlere sahiptir, bu nedenle karışık ilişkilendirmelerin ayrıştırma hatasına neden olması da mümkündür.)


Son olarak, Agda'dan bile daha esnek bir sözdizimine sahip olan teorem kanıtlayıcı / bağımlı olarak yazılan dil Coq var , çünkü sözdizimi uzantıları aslında yeni sözdizimsel yapılar için spesifikasyonlar verilerek ve daha sonra bunları çekirdek dile yeniden yazarak (belirsiz makro benzeri) , Sanırım). Coq'ta, liste sözdizimi [1; 2; 3]standart kitaplıktan isteğe bağlı bir içe aktarmadır. Yeni sözdizimleri değişkenleri bile bağlayabilir!

Bir kez daha, Coq'da, kendi infix operatörlerimizi tanımlayabilir ve onlara öncelik seviyeleri (çoğunlukla 0-99 arasında) ve ilişkilendirmeler verebiliriz. Bununla birlikte, Coq'ta, her öncelik seviyesinin sadece bir ilişkisi olabilir . Dolayısıyla <@, sol çağrışım olarak tanımlayıp sonra @>aynı düzeyde sağ çağrışım olarak tanımlamaya çalışırsak - örneğin, 50 -

Hata: Seviye 50 zaten sağ ilişkilendirici olarak ilan edildi, ancak şimdi sağ ilişkilendirici olması bekleniyor

Coq'taki çoğu operatör 10 ile bölünebilen seviyelerdedir; ilişkilendirilebilirlik sorunları yaşadım (bu düzey ilişkilendirmeler globaldir), genellikle düzeyi her iki yönde de (genellikle yukarı) birer birer çarptım.


2
(Gee, ne tuhaf bir dil seçimi. Programlama dili teorisi üzerine
çalıştığımı

Ayrıntılı cevabınız için çok teşekkürler. BTW, resmi nasıl graphviz
çizdiniz

BTW, neden "öncelik" yerine "sabitlik"?
Basile Starynkevitch

@BasileStarynkevitch: Bu, kastettiğiniz yere bağlı. Coq bölümünde demek istiyorsan, bu sadece bir hataydı :-) (Ve şimdi düzeltildi!)
Antal Spector-Zabusky

1
@BasileStarynkevitch: Ayrıca, resim hakkındaki sorunuzu da kaçırdım! Bunu LaTeX paketi qtree ile çizdim ve Mac'ler için bir LaTeX snippet oluşturucusu LaTeXit'te oluşturdum . İlgili kaynak kodu idi \ttfamily \Tree[.<@ [.<@ [.<@ a b ] [.@> c [.@> d [.@> e f ]]]] g ].
Antal Spector-Zabusky

2

Douglas Crockford tarafından popüler hale getirildiklerinden, Pratt Parsers (veya Yukarıdan Aşağı Operatör Öncelik ayrıştırıcıları) daha yaygın olmaya başladı. Bu ayrıştırıcılar, kuralların sabit bir gramer içine yerleştirilmesi yerine bir operatör önceliği ve ilişkilendirilebilirliği tablosundan çalışır, bu nedenle kullanıcıların kendi operatörlerini tanımlamasına izin veren diller için yararlıdır.

Önce bir ifadenin en soldaki terimini ayrıştırarak, daha sonra uygun şekilde bağlandıkları sürece yeni operatörleri ve sağ el terimlerini tekrar tekrar bağlayarak çalışan bir ayrıştırma işlevine sahiptirler. Sol ilişkisel operatörler, aynı önceliğe ve önceliğe sahip olan sağ el terimlerini bağlarken, sağ ilişkisel operatörler yalnızca öncelik seviyelerine kadar bağlanırlar, ancak bunu içermezler. Bunun yukarıda belirtilen Agda ile aynı ayrıştırma ağacıyla sonuçlandığına inanıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.