Lompat ke konten Lompat ke sidebar Lompat ke footer

Chomsky Hierarchy


Grammar tipe 0α  β         α tidak boleh string kosong.

                            γ A δ  γ β δ         A = non terminal, γ dan δ konteks
                                                                  dari kiri dan kanan dari A


Grammar tipe 0 disebut juga Unrestrected grammars atau
Phrasestructure grammars atau
Semi-thue grammars.


Grammar tipe 1 - Context-sensitive grammars     γ A δ         γ β δ α tidak boleh kosong (β). 

Grammar tipe 2 - Context free grammars (CFG) :    A  β     ruas kiri harus non-terminal tunggal. 

Grammar tipe 3 - Regular grammars :    ruas kanan dari produksi mungkin berupa

                                a. hanya 1 terminal, atau

                                b. 1 non-terminal dan 1 terminal


Top-Down Parser

Dikenal dua macam parser, yaitu Top-down parser dan Bottom-up parser. Top-down parser dimulai dengan root dari parse tree ke bawah.


Left Recursions

Left recursion menimbulkan masalah pada top-down parser.

Misalnya ada grammar:

EE + T | T

TT * F | F

FI | (E)

dan misalnya di-parse ekspresi i+i*i

maka parse tree nya adalah:

left recursion


Cara mengatasi left recursion:

Untuk setiap non-terminal dalam grammar:

Pisahkan produksi yang berbentuk left-recursion dari yang lain.

Misalnya:

A Aα1 | Aα2 | Aα3 | ...            (left-recursion)

Aδ1 | δ2 | δ3| ...

Masukkan non-terminal baru A'

Ubah produksi non-left-recursion di A menjadi:

Aδ1A' | δ2 A' | δ3A'| ...

Ganti produksi left-recursion di A dengan:

A ε | αA'| α'2| αA'| ...


Contoh Soal -1:

Diketahui grammar (ditulis dalam bentuk produksinya saja):

AAc |Ad | e | f

Pisahkan yang left-recursion dan yang non-left-recursion

Left recursion: A Ac | Ad

Non-left recursion: A e | f

Tambahkan non-terminal A'. Pada produksi yang non-left-recursion, ubahlah e menjadi eA' dan f dengan fA'. Pindahkan produksi yang left recursion ke A' dengan ruas kanan dari A' adalah e, cA' dan dA'.

Produksi yang telah diperbaiki adalah sebagai berikut:

A eA' | fA'

A ε | cA' | dA'

Walau ada dua produksi A yang left-recursion namun dapat digabung dengan hanya menambahkan satu non-terminal yang baru.


Contoh Soal-2:

Hilangkan semua left-recursion dari grammar berikut ini:

S aA | b | cS

A Sd | e

Produksi S tidak memerlukan penanganan karena non-left-recursion. Pada ruas kanan produksi A dimulai dengan non-terminal S. Inilah left-recursion. Untuk itu S disubstitusi dengan ruas kanan dari produksi S sehingga menjadi:

A aAd | bd | cSd | e

Perhatikanlah bahwa yang tercetak tebal berasal dari produksi S yang disubstitusikan ke A. Dengan produksi yang baru ini left recursion telah dapat dihindari. Hal ini dapat terjadi karena kita dapat menelusuri bentuk sentensial dari A berikut ini:

Untitled Diagram

Produksi yang baru mengabaikan Sd.


Recursive-Descent Parsing.

Ruas kanan dari produksi biasanya berupa campuran antara terminal dan non-terminal. Fungsi recursive-decent adalah menelusuri grammar di ruas kanan sesuai dengan masukkannya, sampai ditemukan token yang cocok. Tetapi jika ditemukan non-terminal maka akan dipanggil fungsi lain yang bersesuaian dengan non-terminal tersebut. Dengan kata lain setiap non-terminal memiliki fungsi sendiri-sendiri.

Contoh:

S - > bA | c

A-> dS | e

Fungsi S mengecek b; untuk A akan ditelusuri melalui fungsi A. Jadi jika ada 2 non-terminal maka dibutuhkan 2 fungsi. Fragmen dari fungsi-fungsi tersebut adalah:

Fungsi S:

1. function S:boolean;
2.     begin
3.         S:=true;
4.         if token_is('b') then
                if A then    {mencoba fungsi S -> bA}
                    writeln(S->bA')
                else
                    S:=false
            else
                if token_is('c' then
                    writeln('S->c')
                else
                begin
                    error('S');
                    S:=false
                end;
                end; {S}


Fungsi A:

1. function A:boolean;
2.     begin
3.         A:=true;
4.         if token_is('d') then
5.        begin
6.            if S then
7.                if token_is('d') then
8.                    writeln('A->dSd')
9.                 else
10.                begin {error, string masukan tdk diakhiri dengan 'd')
11.                    error('A')
12.                    A :=false
13.                end
14.             else
15.                A:=false {error, token tengahnya tidak S}
16.             end
17.            else
18.                if token_isi('e') then
19.                    writeln('A->e')
20.            else
21.                begin {seluruh bagian kanan fungsi A tidak terpenuhi}
22.                    error('A');
23.                        A:=false
24.                end
25.            end; {A}

Misalnya string masukkannya adalah bdcd

left recursion (2)