SORU
11 ŞUBAT 2010, PERŞEMBE


8-bit gömülü sistemler üzerinde kullanılabilir flex/bison için bir alternatif var mı?

C AVR mikroişlemci avr-gcc araç zinciri kullanarak bir egzersiz olarak dil gibi basit bir TEMEL için küçük bir tercüman yazıyorum. Ancak, eğer lexer ve ayrıştırıcı yazıyor bana yardımcı olabilecek herhangi bir açık kaynak araçlar orada olup olmadığını merak ediyorum.

Eğer bu benim Linux kutusu üzerinde çalıştırmak için, yazarsam, flex/bison kullanabilirim. Bunu yapmak zorundayım, ya da kendimi kısıtlanmış 8-bit platform?

CEVAP
25 ŞUBAT 2010, PERŞEMBE


Kolay bir yol ayrıştırıcıları kod, mekan biraz Dar,-El kod özyinelemeli kökenli bir ayrıştırıcı gerekir; bu aslında LL(1) ayrıştırıcıları. Bu "" gibi Temel. Basit olarak hangi diller için özellikle etkilidir (Bu 70! arkada) birkaç yaptım. İyi haber bu kütüphane herhangi bir kod içermez; yazmak sadece.

Eğer zaten bir gramer varsa çok kolay bir kod. İlk olarak, sol özyinelemeli kuralları (örneğin, X = X Y ) kurtulmak gerekir. Bu genellikle oldukça kolay yapmak için, bir egzersiz olarak bırakıyorum. (Liste-şekillendirme kuralları için bunu yapmak zorunda değilsin; bakın tartışma aşağıda).

Eğer form BNF kural varsa, o zaman:

 X = A B C ;

bir boolean döndüren kural (X, A, B, C) her madde için bir alt yordam oluşturun "ilgili sözdizimi oluşturmak gördüm" diyerek. X, kodu:

subroutine X()
     if ~(A()) return false;
     if ~(B()) { error(); return false; }
     if ~(C()) { error(); return false; }
     // insert semantic action here: generate code, do the work, ....
     return true;
end X;

A, B, benzer şekilde, C

Eğer bir simge bir terminal ise, denetleyen bir kod yazmak terminal oluşturan karakter dizesi giriş akışı. E. g, bir Dizi için, giriş akışı basamak içerir ve önceden kontrol edin giriş akışı rakamını geçmiş imleç. Bu özellikle kolaydır bir tampon (TEMEL için, bir defada bir satır almak eğilimindedir)ayrıştırma vardır sadece ilerleyen veya arabellek işaretçi tarama değil ilerleyen. Bu kod aslında çözümleyici lexer parçasıdır.

Eğer BNF senin özyinelemeli kural ise, hiç merak etme. Sadece özyinelemeli çağrı kodu. Bu gibi dilbilgisi kuralları işler:

T  =  '('  T  ')' ;

Bu gibi kodlanmış olabilir:

subroutine T()
     if ~(left_paren()) return false;
     if ~(T()) { error(); return false; }
     if ~(right_paren()) { error(); return false; }
     // insert semantic action here: generate code, do the work, ....
     return true;
end T;

Alternatif BNF bir kural varsa:

 P = Q | R ;

alternatif seçenekler ile kod P sonra:

subroutine P()
    if ~(Q)
        {if ~(R) return false;
         return true;
        }
    return true;
end P;

Bazen kurallar listesi oluşturan karşılaşma olacak. Bu özyinelemeli sol olma eğilimindedir, ve bu durumda kolayca ele alınır. Örnek:

L  =  A |  L A ;

Bu gibi kod:

subroutine L()
    if ~(A()) then return false;
    while (A()) do // loop
    return true;
end L;

Bir iki gün içinde birkaç yüz dilbilgisi kuralları bu şekilde kodu. Doldurmak için daha fazla ayrıntı yok, ancak temelleri burada fazlasıyla yeterli olmalı.

Eğer varsagerçektenmekan biraz dar, uygulayan bir sanal makine inşa edebilirsiniz bu fikirler. O 8K 16 bit kelimeleri ne zaman 70'lerde, tekrar yaptım.


Eğer elle bu kod, istemesen bile, temelde aynı şeyi üreten bir metacompiler ile otomatik hale getirebilirsiniz. Bu akıl almaz bir teknik eğlenceli ve gerçekten bütün işi yapıyor bu bile çok büyük gramerleri için ayırın.

Ağustos 2014:

Bir sürü istek var bir çözümleyici ile bir AST inşa etmek için nasıl". Aslında bu cevabı karmaşık olan bu ayrıntılar, için, benim diğer http://stackoverflow.com/a/25106688/120163 cevap bakın

Temmuz 2015:

Basit bir ifade değerlendiricisi yazmak istediğim ne çok insan var. "AST builder" link yukarıda; sadece aritmetik yerine bina ağaç düğümlerini gösteriyor.bu şeylere benzer şeyler yaparak bunu yapabilirsiniz Burada an expression evaluator done this way.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Gavin Hoey

    Gavin Hoey

    21 Aralık 2007
  • Paul Schroder

    Paul Schrode

    30 Kasım 2007
  • RayperEnglishKnight

    RayperEnglis

    24 Kasım 2008