5

Próbowałem zaimplementować parser topologii LL (1) dla języka kalkulatora. Pozwala nam tylko sumować, odejmować, dzielić i mnożyć liczby. Bez nawiasów.Czy lewy operator asocjacyjny może być wyrażony w taki sposób, aby zrozumieć parsery LL (1)?

S -> A 

A -> B + A 
    | B - A 
    | B 

B -> int * B 
    | int/B 
    | int 

Ponieważ gramatyka nie nadaje się do LL (1) parser, musiałem go zmienić sporo:

S -> A 

A -> B A' 
A'-> + A 
    | - A 
    | λ 

B -> int B' 
B'-> * B 
    |/B 
    | λ 

Problem polega na tym, że teraz gramatyka nie jest wiązanie lewe dla 4 pokazano operatorów, i potrzebuję, żeby tak było. Jak rozwiązać ten problem? Czy można to osiągnąć?

+1

Przypuszczam, że nie szukasz odpowiedzi "nie używaj parsera LL (1), a następnie" :). Ale taka jest rzeczywistość: parsery 'LL (1)' nie pasują do wyrażeń parsujących; jeśli z jakiegoś powodu nie chcesz używać 'LR (1)', napisz parser Pratta lub parser hierarchii operatorów (zobacz "Algorytm sekwencji manewrowych") – rici

+1

Po prostu uczę się o parserach. Zamierzałem spróbować zaimplementować prosty język kalkulatora dla kilku rodzajów analizatorów składni. Czy twierdzisz, że nie można wykonać kalkulatora przy pomocy LL (1)? –

+0

Nie twierdzę, że to niemożliwe, tylko że nie jest trywialne. Możesz to zrobić za pomocą parsera LL (1), aby wygenerować drzewo analizy dla zmodyfikowanej gramatyki, a następnie odwrócić transformację na drzewie analizy, aby utworzyć drzewo analizy dla oryginalnej gramatyki. – rici

Odpowiedz

6

Możesz uzyskać lewostronność, zastępując rekurencję za pomocą iteracji. Poniższy sort-pseudocode bezpośrednio oblicza wartości tylko dla prostoty, ale można wygenerować drzewo analizowania przy użyciu tej samej metody.

function A() { 
    val = B(); 
    t = peek(); 
    while (t=='+' || t=='-') { 
    match(t); 
    val1 = B(); 
    if (t=='+') 
     val = val + val1; 
    else 
     val = val - val1; 
    t = peek(); 
    } 
    return(val) 
} 

gdzie peek() zwraca następny znak bez jedzenia i match() zjada następny token. Zrobiłbyś to samo dla B().

Powiązane problemy