Aritmetik ifadeler dilbilgisi dönüşümü


9

Theodore Norvell (1999) tarafından Özyinelemeli İniş ile İfadeleri Ayrıştırma makalesinde yazar aritmetik ifadeler için aşağıdaki dilbilgisi ile başlar:

E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v

bu oldukça kötü, çünkü belirsiz ve sol yinelemeli. Böylece sol özyinelemeyi ondan çıkarmaya başlar ve sonucu şöyledir:

E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"

Ama bu sonuca nasıl ulaştığını anlayamıyorum. Sol özyinelemeyi kendim kaldırmaya çalıştığımda, bunu şu şekilde yapıyorum:

  1. Firs, bir grupta özyineleme bırakmayan üretimleri, diğer bir grupta diğer (sol özyinelemeli) üretimleri bir araya getiriyorum:

    E --> E "+" E | E "-" E | E "*" E | E "/" E | E "^" E     // L-recursive
    E --> v | "(" E ")" | "-" E
  2. Sonra, onları adlandırıyorum ve daha kolay manipülasyonlar için faktör:

    E --> E B E  // L-recursive; B stands for "Binary operator"
    E --> P  // not L-recursive; P stands for "Primary Expression"
    P --> v | "(" E ")" | U E   // U stands for "Unary operator"
    B --> "+" | "-" | "*" | "/" | "^"
    P --> "-"

    Şimdi sadece ilk iki prodüksiyonla uğraşmam gerekiyor, ki bu artık başa çıkması daha kolay.

  3. Bu ilk iki prodüksiyonu L-özyinelemesiz üretimden (basitçe PBirincil ifade) başlayarak ve onu T, orijinal üretimin geri kalanı olarak ilk sol özyinelemeli nonterminalden daha az olarak tanımladığım isteğe bağlı Kuyruk ile izleyerek yeniden yazıyorum. (olduğunu, sadece B E) Tail ardından T, veya hangi boş olabilir:

    E --> P T
    T --> B E T |

    (kuyruk için boş alternatifi not edin).

  4. EBNF'de şu şekilde yeniden yazabileceğim bu iki yapım şöyle:

    E --> P {B E}

    ki bu neredeyse yazarın elde ettiği şey, ama Ebunun yerine Psıfır veya daha fazla tekrarlama modelinin (Kuyruk) içinde var. Sahip olduğu diğer prodüksiyonlarla aynı:

    P --> v | "(" E ")" | U E
    B -> "+" | "-" | "*" | "/" | "^"
    U -> "-"

    ama burada da ilk üretimim Eyerine var .PP

Benim sorum şu: Ne özlüyorum? Autor ile aynı formun aynısını almak için sözdiziminde hangi cebirsel dönüşüme ihtiyacım var? Ben yerine koyma denedim E, ama bu sadece beni döngülere götürüyor. Ben yerine nasılsa ihtiyaç şüpheli Piçin E, ama bunu haklı çıkarmak için herhangi bir yasal dönüşümü bilmiyorum. Belki de son eksik adımın ne olduğunu biliyorsunuzdur?


Lütfen biçimlendirme için LaTeX kullanmayı düşünün. Bir astar için buraya bakın . ( Bu durumda LaTeX'in uygunluğu hakkında bir tartışma için buraya bakın .)
Raphael

Yanıtlar:


8

Eksik adım:

E --> P T
T --> B E T |

E harfini T ile yeniden yaz:

E --> P T
T --> B P T T | 

T'yi basitleştirin:

E --> P T
T --> B P T | 

Eşittir:

E --> P T
T --> {B P}

Ve işte buradasın.


1
İyi bir cevap için teşekkürler :-) Şimdi neyi kaçırdığımı görüyorum: Bunun yerine başka bir şey koydum ve sorun buydu. Ama yine de küçük bir parça anlamıyorum: Bunları Tbirlikte güvenli bir şekilde bir araya getirebileceğinizi nereden biliyorsunuz T? Bunun için bir kural var mı? (Bunun bir şekilde Boole cebir mantığında "aa = a" yazan kurala benzer olabileceğinden şüpheleniyorum.)
SasQ

BTW bu yazı neden cstheory.sx'ten taşındı ve fark nedir? Gelecekte hatalardan kaçınmayı bilmek istiyorum.
SasQ

2
@SasQ CSTheory yalnızca teorik bilgisayar bilimlerindeki araştırma düzeyindeki sorular içindir, ayrıntılar için CSTheory'nin SSS bölümüne bakın.
Juho

1
@SasQ: TxTT|ε üretir x* ve öyle TxT|ε. Daha genel,L*L*=L* için Lherhangi bir dil. Boş kelimeye sahip olmanınεsağ taraf çok önemli olduğu için; bu, tüm dilbilgisi parçaları için geçerli değildir,L+L+L+.
Raphael

@Raphael: Bunun idempotence kuralıyla bir ilgisi var *mı? "Dragon Book" da gördüm (3.3, s.91) x** = x*. Kullandığın kural bu mu?
SasQ
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.