SORU
26 AĞUSTOS 2008, Salı


Denklem (ifade) öncelik ile ayrıştırıcı?

Bir denklem ayrıştırıcı işleyen algoritma yığın ikili ( , -, |, &, *, /, vb.) basit operatörler, bir tekli kullanarak geliştirdim (!) operatörler ve parantez.

Bu yöntemi kullanarak, ancak, her şey aynı öncelik öncelik zorunlu olmasına rağmen sağ operatörü ne olursa olsun, sol, değerlendirilen bu parantez kullanarak zorunda kalıyorum.

Şimdi "1 11*5 verir gibi 60, 56" bekliyor olabilir. değil mi yani

Bu, geçerli proje için uygun iken, daha sonraki projeleri için kullanabileceğiniz genel amaçlı bir rutin yapmak istiyorum.

Açıklık getirmek için düzenlenmiş:

Öncelik ile denklemler ayrıştırma için iyi bir algoritma nedir?

Bir şey uygulamak için basit ilgileniyorum ve kendimi mevcut kod ile lisans sorunları önlemek için kod olabilir.

Dilbilgisi:

Dilbilgisi soruyu anlamadım - bunları elle yazdım. YACC gerek görmüyorum bu kadar basit ya da Bizon. Ben sadece denklemler bu dizelerle olarak hesaplamak gerekir"2 3 * (42/13)".

Dil:

C yapıyorum, ama bir algoritma, belirli bir dil değil, bir çözüm ilgileniyorum. C ihtiyaç doğması halinde başka bir dile dönüştürmek için kolay olacak o kadar düşük seviyede.

Kod Örneği

Yukarıda bahsettiğim test code for the simple expression parser yayınlanmıştır. Proje gerekliliklerini hiç projeye dahil değildi olarak performans veya alan kodu optimize etmek için gerekli çok değişmiş. Orijinal ayrıntılı biçimde ve kolayca anlaşılabilir olmalıdır. Eğer başka bir operatör önceliği açısından bunu yaparsam, muhtemelen sadeliği, programın geri kalanıyla uyumlu çünkü the macro hack seçeceğim. Ben hiç gerçek bir proje bu, olsa da, daha kompakt/hızlı bir çözümleyici için gidiyorum.

Soru ile ilgili

Smart design of a math parser?

CEVAP
6 EYLÜL 2008, CUMARTESİ


shunting yard algorithm Bu iş için doğru araçtır. Wikipedia bu konuda gerçekten kafa karıştırıcı, ama temelde algoritma şu şekilde çalışır:

Söyle, 2 * 1 3 4 değerlendirmek istiyorum. Sezgisel olarak, "" 2 * 3 ilk yapmanız gereken, ama bu sonucu almak mı? Anahtar soldan sağa dize tarama yaparken, işletmeci o zaman bir operatör değerlendirecektir fark etmektirizlerya da eşit daha düşük bir önceliğe sahiptir. Örnek bağlamında, burada ne yapmak istiyorsunuz:

  1. Bak: 1 2 bir şey yapma.
  2. Şimdi 1 2 * 3, hala bir şey yapma bak.
  3. Şimdi 1 2 * 3 4 şimdi 2 * 3 biliyorsunuz, bir sonraki operatör daha düşük bir önceliğe sahip olduğundan, değerlendirilecek bak.

Bunu nasıl uygular?

İki yığınları, sayılar ve operatörler için başka bir sahip olmak istiyorum. Üzerine sayılar her zaman yığın itin. Karşılaştırmak her yeni operatör olan en üstünde yığın halinde bir üst yığını var daha yüksek öncelik, patlat gitsin operatörü yığın, pop işlenen off numarasını yığını, uygulamak operatör ve itme sonucu üzerine numarasını yığını. Şimdi siz yığın üst ile karşılaştırma operatörü tekrarlayın.

Örneğe dönecek olursak, bu gibi çalışır:

[ ]N = = [ ] Ops

  • 1 okuyun. N = [1], Ops = [ ]
  • Okuyun . N = [1], Ops = [ ]
  • 2 okuyun. N = [1 2], Ops = [ ]
  • * *0 okuma. N = [1 2], Ops = [ *]
  • 3 okuyun. N = [1 2 3], Ops = [ *]
  • Okuyun . N = [1 2 3], Ops = [ *]
    • N. N üzerine Pop 3, 2 ve yürütmek 2*3 ve itin sonuç = [1 6], = [ ] Ops
    • ilişkisel sol, 1, 6 da pop ve yürütmek istiyorsun . N = [7], Ops = [].
    • Nihayet [ ] push yığın operatör. üzerine N = [7], Ops = [ ].
  • 4 okuyun. [7 4] N =. = [ ] Ops.
  • Yığınlar şimdi boş istediğiniz kadar giriş kapalı tükendi. Bunun üzerine sonuç 11 olacaktır.

İşte, o kadar zor değil, değil mi? Ve herhangi bir gramer veya ayrıştırıcı üretimi için Hayır dualar ediyor.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Break

    Break

    10 Aralık 2005
  • Matt Harding

    Matt Harding

    23 Mayıs 2006
  • natescamp

    natescamp

    30 NİSAN 2009