Earley ayrıştırıcı - Earley parser

Gelen bilgisayar bilimleri , Earley ayrıştırıcı bir olan algoritma için ayrıştırma dizeleri belirli bir aittir bağlam serbest dili olsa da, bazı null grammars ile ilgili sorunlar ortaya çıkabilir (tipe bağlı olarak). Adını mucidi Jay Earley'den alan algoritma, dinamik programlamayı kullanan bir grafik ayrıştırıcıdır ; esas olarak hesaplamalı dilbilimde ayrıştırma için kullanılır . İlk olarak 1968'deki tezinde tanıtıldı (ve daha sonra bir dergide kısaltılmış, daha okunaklı bir biçimde ortaya çıktı).

Earley ayrıştırıcıları, derleyicilerde daha tipik olarak kullanılan ancak yalnızca sınırlı dil sınıflarını işleyebilen LR ayrıştırıcıları ve LL ayrıştırıcılarının aksine, bağlamdan bağımsız tüm dilleri ayrıştırabildikleri için çekicidir . Earley ayrıştırıcısı , n'nin ayrıştırılan dizenin uzunluğu, belirsiz olmayan dilbilgileri için ikinci dereceden zaman ve tüm deterministik bağlamdan bağımsız dilbilgisi için doğrusal zaman olduğu genel durumda kübik zamanda yürütülür . Kurallar sola özyinelemeli olarak yazıldığında özellikle iyi performans gösterir .

Earley tanıyıcı

Aşağıdaki algoritma Earley tanıyıcıyı açıklar. Tanıyıcı, tanıdığı gibi bir ayrıştırma ağacı oluşturmak için kolayca değiştirilebilir ve bu şekilde bir ayrıştırıcıya dönüştürülebilir.

algoritma

Aşağıdaki tariflerde, α, β, ve herhangi birini temsil y dize ve terminallerine / nonterminallerdir (dahil boş dizge ), X ve Y, bir tek nonterminallerin temsil eder ve bir terminal sembolü temsil eder.

Earley'in algoritması yukarıdan aşağıya bir dinamik programlama algoritmasıdır. Aşağıda, Earley'nin nokta gösterimini kullanıyoruz: bir X → αβ üretimi verildiğinde, X → α • β gösterimi, α'nın zaten ayrıştırıldığı ve β'nın beklendiği bir durumu temsil eder.

Giriş konumu 0, girişten önceki konumdur. Giriş konumu N kabul ettikten sonra pozisyondur n inci belirteç. (Gayrı resmi olarak, giriş konumları belirteç sınırlarındaki konumlar olarak düşünülebilir .) Her giriş konumu için ayrıştırıcı bir durum kümesi oluşturur . Her durum, aşağıdakilerden oluşan bir tanımlama grubudur (X → α • β, i ).

  • şu anda eşleşen üretim (X → α β)
  • o üretimdeki mevcut konum (nokta ile gösterilir)
  • bu üretimin eşleşmesinin başladığı girdideki i konumu : başlangıç ​​konumu

(Earley'nin orijinal algoritması, duruma ileriye dönük bir bakış içeriyordu; daha sonraki araştırmalar bunun ayrıştırma verimliliği üzerinde çok az pratik etkisi olduğunu gösterdi ve daha sonra çoğu uygulamadan çıkarıldı.)

k giriş konumunda ayarlanan duruma S( k ) adı verilir . Ayrıştırıcı, yalnızca üst düzey kuraldan oluşan S(0) ile tohumlanır. Ayrıştırıcı daha sonra art arda üç işlemi yürütür: tahmin , tarama ve tamamlama .

  • Tahmin : (X → α • Y β, j ) formunun S( k ) içindeki her durumu için (burada j yukarıdaki gibi başlangıç ​​konumudur), her biri için S( k )' ye (Y → • γ, k ) ekleyin. sol tarafta Y ile dilbilgisinde üretim (Y → γ).
  • Tarama : Eğer bir giriş akışı bir sonraki sembol S (her durum için, bir K formu) (X → α • bir β, j ), eklenti (X → α bir • β, j S) ( k +1).
  • Tamamlama : (Y → γ •, j ) formunun S( k ) içindeki her durumu için (X → α • Y β, i ) formunun S( j ) içindeki tüm durumları bulun ve (X → α Y) ekleyin • β, i ) ila S( k ).

Durum kümesine yinelenen durumlar eklenmez, yalnızca yenileri eklenir. Bu üç işlem, kümeye yeni durum eklenemeyecek duruma gelene kadar tekrarlanır. Küme genellikle, ne tür bir durum olduğuna bağlı olarak gerçekleştirilecek işlemle birlikte işlenecek bir durum sırası olarak uygulanır.

Algoritma, (X → γ •, 0) S( n ) ile biterse kabul eder , burada (X → γ) üst düzey kural ve n giriş uzunluğudur, aksi halde reddeder.

sözde kod

Daniel Jurafsky ve James H. Martin tarafından Speech and Language Processing'den uyarlanmıştır ,

DECLARE ARRAY S;

function INIT(words)
    S  CREATE_ARRAY(LENGTH(words) + 1)
    for k  from 0 to LENGTH(words) do
        S[k]  EMPTY_ORDERED_SET

function EARLEY_PARSE(words, grammar)
    INIT(words)
    ADD_TO_SET((γ  S, 0), S[0])
    for k  from 0 to LENGTH(words) do
        for each state in S[k] do  // S[k] can expand during this loop
            if not FINISHED(state) then
                if NEXT_ELEMENT_OF(state) is a nonterminal then
                    PREDICTOR(state, k, grammar)         // non_terminal
                else do
                    SCANNER(state, k, words)             // terminal
            else do
                COMPLETER(state, k)
        end
    end
    return chart

procedure PREDICTOR((A  α•Bβ, j), k, grammar)
    for each (B  γ) in GRAMMAR_RULES_FOR(B, grammar) do
        ADD_TO_SET((B  •γ, k), S[k])
    end

procedure SCANNER((A  α•aβ, j), k, words)
    if a  PARTS_OF_SPEECH(words[k]) then
        ADD_TO_SET((A  αa•β, j), S[k+1])
    end

procedure COMPLETER((B  γ•, x), k)
    for each (A  α•Bβ, j) in S[x] do
        ADD_TO_SET((A  αB•β, j), S[k])
    end

Örnek

Aritmetik ifadeler için aşağıdaki basit dilbilgisini göz önünde bulundurun:

<P> ::= <S>      # the start rule
<S> ::= <S> "+" <M> | <M>
<M> ::= <M> "*" <T> | <T>
<T> ::= "1" | "2" | "3" | "4"

Giriş ile:

2 + 3 * 4

Bu durum kümelerinin sırasıdır:

(nolu belirtin.) Üretme (Menşei) Yorum Yap
S(0): • 2 + 3 * 4
1 P → • S 0 kuralı başlat
2 S → • S + M 0 (1)'den tahmin et
3 S → • M 0 (1)'den tahmin et
4 M → • M * T 0 (3)'ten tahmin et
5 M → • T 0 (3)'ten tahmin et
6 T → • sayı 0 (5)'ten tahmin et
S(1): 2 • + 3 * 4
1 T → sayı • 0 S(0)(6)'dan tarama
2 M → T • 0 (1) ve S(0)(5)'ten tamamlayın
3 M → M • * T 0 (2) ve S(0)(4)'ten tamamlayın
4 S → M • 0 (2) ve S(0)(3)'ten tamamlayın
5 S → S • + M 0 (4) ve S(0)(2)'den tam
6 P → S • 0 (4) ve S(0)(1)'den tamamlayın
S(2): 2 + • 3 * 4
1 S → S + • M 0 S(1)(5)'ten tarama
2 M → • M * T 2 (1)'den tahmin et
3 M → • T 2 (1)'den tahmin et
4 T → • sayı 2 (3)'ten tahmin et
S(3): 2 + 3 • * 4
1 T → sayı • 2 S(2)(4)'ten tarama
2 M → T • 2 (1) ve S(2)(3)'ten tamamlayın
3 M → M • * T 2 (2) ve S(2)(2)'den tamamlayın
4 S → S + M • 0 (2) ve S(2)(1)'den tamamlayın
5 S → S • + M 0 (4) ve S(0)(2)'den tam
6 P → S • 0 (4) ve S(0)(1)'den tamamlayın
S(4): 2 + 3 * • 4
1 M → M * • T 2 S(3)(3)'ten tarama
2 T → • sayı 4 (1)'den tahmin et
S(5): 2 + 3 * 4 •
1 T → sayı • 4 S(4)(2)'den tarama
2 M → M * T • 2 (1) ve S(4)(1)'den tamamlayın
3 M → M • * T 2 (2) ve S(2)(2)'den tamamlayın
4 S → S + M • 0 (2) ve S(2)(1)'den tamamlayın
5 S → S • + M 0 (4) ve S(0)(2)'den tam
6 P → S • 0 (4) ve S(0)(1)'den tamamlayın

Durum (P → S •, 0) tamamlanmış bir ayrıştırmayı temsil eder. Bu durum, tam cümleler olan S(3) ve S(1)'de de görülür.

Ayrıştırma ormanı oluşturma

Earley'in tezi, bir Earley öğesindeki her bir terminal olmayandan, tanınmasına neden olan öğelere bir dizi işaretçi ekleyerek ayrıştırma ağaçları oluşturmaya yönelik bir algoritmayı kısaca açıklar. Ancak Tomita , bunun semboller arasındaki ilişkileri hesaba katmadığını fark etti, bu yüzden dilbilgisini düşünürsek S → SS | b ve bbb dizesi, yalnızca her S'nin bir veya iki b ile eşleşebileceğini ve böylece bb ve bbbb için sahte türevler ve bbb için iki doğru türev ürettiğini not eder.

Diğer bir yöntem, her Earley öğesini, üçlü (s, i, j) ile etiketlenmiş bir paylaşılan paketlenmiş ayrıştırma ormanı (SPPF) düğümüne bir işaretçi ile artırarak, ilerledikçe ayrıştırma ormanı oluşturmaktır; burada s bir sembol veya bir LR(0'dır). ) öğe (noktalı üretim kuralı) ve i ve j, bu düğüm tarafından türetilen girdi dizesinin bölümünü verir. Bir düğümün içeriği ya tek bir türetme veren bir çift alt işaretçi ya da her biri bir türetmeyi temsil eden bir çift işaretçi içeren "paketlenmiş" düğümlerin bir listesidir. SPPF düğümleri benzersizdir (belirli bir etikete sahip yalnızca bir tane vardır), ancak belirsiz ayrıştırmalar için birden fazla türetme içerebilir . Bu nedenle, bir işlem bir Earley öğesi eklemese bile (çünkü zaten var), öğenin ayrıştırma ormanına yine de bir türetme ekleyebilir.

  • Öngörülen öğelerin boş bir SPPF işaretçisi var.
  • Tarayıcı, taradığı terminal olmayanı temsil eden bir SPPF düğümü oluşturur.
  • Ardından, tarayıcı veya tamamlayıcı bir öğeyi ilerlettiğinde, çocukları noktası ilerletilen öğeden düğüm olan bir türetme ve üzerinde ilerletilen yeni sembolün (terminal olmayan veya tamamlanmış öğe) türevini eklerler.

SPPF düğümleri hiçbir zaman tamamlanmış bir LR(0) öğesiyle etiketlenmezler: bunun yerine üretilen sembolle etiketlenirler, böylece hangi alternatif üretimden geldiklerine bakılmaksızın tüm türevler tek bir düğüm altında birleştirilir.

Optimizasyonlar

Philippe McLean ve R. Nigel Horspool, "A Faster Earley Ayrıştırıcı" adlı makalelerinde, Earley ayrıştırmayı LR ayrıştırma ile birleştirir ve büyüklük sırasına göre bir gelişme sağlar.

Ayrıca bakınız

alıntılar

Diğer referans malzemeleri

Uygulamalar

C, C++

Haskell

Java

  • [1] – Earley algoritmasının bir Java uygulaması
  • PEN – Earley algoritmasını uygulayan bir Java kitaplığı
  • Pep – Earley algoritmasını uygulayan ve ayrıştırma yapıları olarak tablolar ve ayrıştırma ağaçları sağlayan bir Java kitaplığı
  • digitalheir/java-probabilistic-earley-parser - belirsiz bir cümleden en olası ayrıştırma ağacını belirlemek için yararlı olan olasılıksal Earley algoritmasını uygulayan bir Java kitaplığı

C#

  • coonsta/earley - C# dilinde bir Earley ayrıştırıcısı
  • patrickhuber/pliant - Marpa tarafından benimsenen iyileştirmeleri birleştiren ve Elizabeth Scott'ın ağaç oluşturma algoritmasını gösteren bir Earley ayrıştırıcısı.
  • ellisonch/CFGLib - C# için Olasılıksal Bağlamdan Bağımsız Dilbilgisi (PCFG) Kitaplığı (Earley + SPPF, CYK)

JavaScript

OCaml

  • Simple Earley - Belgelerle birlikte basit bir Earley benzeri ayrıştırma algoritmasının uygulanması.

Perl

  • Marpa::R2 – bir Perl modülü. Marpa , Joop Leo, Aycock ve Horspool tarafından yapılan iyileştirmeleri içeren bir Earley algoritmasıdır.
  • Parse::Earley – Jay Earley'in orijinal algoritmasını uygulayan bir Perl modülü

piton

  • Lark – bir SPPF çıktısı veren bir Earley ayrıştırıcısının nesne yönelimli, prosedürel uygulaması.
  • NLTK – Earley ayrıştırıcılı bir Python araç takımı
  • Spark – Earley ayrıştırıcısını uygulayan Python için nesne yönelimli küçük bir dil çerçevesi
  • spark_parser - yukarıdaki Spark ayrıştırıcısının hem Python 3 hem de Python 2'de çalışan güncellenmiş ve paketlenmiş sürümü
  • earley3.py – ayrıştırma ormanı ve örneklerin oluşturulması da dahil olmak üzere 150 satırdan daha az kodda algoritmanın bağımsız bir uygulaması
  • tjr_python_earley_parser - Python'da minimal bir Earley ayrıştırıcısı

Ortak Lisp

  • CL-Earley-parser - bir Earley ayrıştırıcı uygulayan bir Common Lisp kitaplığı

Şema, Raket

Wolfram

  • uygunEarleyParser - Bazı temel test durumları ile Wolfram programlama dilinde bir Earley ayrıştırıcısının temel bir minimal uygulaması .

Kaynaklar