Normal İfadelerin dilinin ayrıştırılması için aşağı itmeli bir otomata ihtiyacı var mı?


12

Ben daha sonra eşleşen amaçlar için bir dize karşı NFA çalıştırabilirsiniz böylece bir kullanıcı girilen düzenli ifade NFA dönüştürmek istiyorum. Düzenli ifadeleri ayrıştırmak için kullanılabilecek minimum makine nedir?

Köşeli parantezlerin sayılması, sayma ihtiyacı anlamına geldiğinden ve bir DFA / NFA rasgele sayma gerçekleştiremediğinden aşağı itmeli bir otomat olması gerektiğini varsayıyorum. Bu varsayım doğru mu? Örneğin, a (bc *) d ifadesi, parantez içindeki alt ifadenin doğru şekilde işlenmesi için bir PDA gerektirir.


1
Tam olarak "ayrıştırma" ile ne demek istiyorsun? Girişin gerçekten düzenli bir ifade olup olmadığını kontrol etmek mi, yoksa daha karmaşık bir şeyiniz mi var, örneğin ilgili NFA'nın açıklamasını çıkaran bir makine mi? (girişin gerçekten normal bir ifade olup olmadığından emin değilseniz ve bunu kontrol etmeniz gerekiyorsa, parantezin doğru olduğunu ve normalde bir yığın kullanmak anlamına geldiğini kontrol edebilmeniz gerekir.)
Kaveh

Yanıtlar:


8

Haklısın. Standart teknikler kullanılarak düzenli ifadelerin sözdiziminin düzenli olmadığını göstermek kolaydır .

R,EG,(p)p

Bununla birlikte, muhtemelen bir PDA'yı elle kodlamak istemezsiniz. ANTLR veya byacc gibi bir ayrıştırıcı jeneratör kullanmayı düşünün . Öte yandan, ayrıştırıcıları kendiniz programlayarak dillerin ayrıştırılmasını araştırmak istiyorsanız, CYK , Earley , özyinelemeli iniş ve LR gibi diğer temel ayrıştırma algoritmalarıyla devam etmelisiniz .


Teşekkürler. Bu görevler için kod yazma daha iyi anlaşılması oluşturur ve bizon vb Lex gibi mevcut kamu, yacc gibi verimli olarak olmak üzere tasarlanmamıştır
Phil Wright

@PhilWright: Anlıyorum, güzel! Bu dava için başka göstergelerde de editörlük yaptım.
Raphael

Bunun için elle kodlanmış bir özyinelemeli iniş ayrıştırıcısını tercih ederim.
Dave Clarke

Bunun için elle bir ayrıştırıcı yazıyorsanız, yinelemeli iniş (faktoring ve masajdan sonra) bir seçenektir, C < sites.google.com/site/lccretargetablecompiler > için LCC ayrıştırıcısı birçok operatörü işlemek için ilginç bir işe sahiptir. Ancak el yapımı için belki de en kolayı öncelik ayrıştırmadır.
vonbrand

3

Jukka'nın da cstheory'deki " Düzenli ifadeleri düzenli ifadelerle eşleştirme " sorusuna hoş bir cevabı okumanızı tavsiye ederim . Bir alıntı:

Örneğin, "sıkıştırılmış" düzenli ifadeler elde etmek için standart gösterimi aşağıdaki gibi değiştirebiliriz :

  • ('S dizisinden oluşan herhangi bir öneki kaldırmanıza izin verilir
  • ) Adlı bir diziden oluşan tüm sonekleri kaldırma izniniz var.

Yani, ((a|b)*c)de(f|g)örneğin aşağıdaki formlardan herhangi biri kullanılarak "sıkıştırılmış" gösterimde ifade edilebilir: a|b)*c)de(f|gveya ((a|b)*c)de(f|gveya (a|b)*c)de(f|g).

[...]

"Sıkıştırılmış" gösterim (normal ifadenin) normal bir dildir.

Bu sadece normal ifade diliyle ilgili ilginç (bana göre) "farklı bir görüşe" bir bağlantıdır; aşağıdaki yorumlarda vurgulandığı gibi, bir sözdizimi ağacı oluşturmak için yararlı değildir. Eğer ayrıştırıcınızı el ile kodlamak istiyorsanız, size kod yazımı " Writing-own-regular-expression-parser " hakkındaki bu basit makaleyi önereceğim .


Jukka aslında parantezlerin dengelenmesi gereksinimini ortadan kaldırır. Bunun gerçekte nerede yapıldığını bilmiyorum, ama anlambilimi değiştirerek sözdizimini "basitleştirebilirsiniz".
Raphael

4
Siz (ve Jukka) normal ifadeleri ayrıştırmıyorsunuz, yalnızca onları tanıyorsunuz. "Evet, bu (sıkıştırılmış) bir normal ifade."
Gilles 'SO- kötü olmayı bırak'
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.