Apa contoh paling sederhana di luar sana untuk menjelaskan perbedaan antara Pohon Parse dan Pohon Sintaks Abstrak?

14

Menurut pemahaman saya, pengurai membuat pohon pengurai, dan kemudian membuangnya. Namun, ia juga dapat memunculkan pohon sintaksis abstrak, yang seharusnya digunakan oleh kompiler.

Saya mendapat kesan bahwa baik pohon parse dan pohon sintaksis abstrak dibuat di bawah tahap parsing. Lalu dapatkah seseorang menjelaskan mengapa ini berbeda?

Logika Combinator
sumber
3
Mengapa mereka harus berbeda? Tidak bisakah mereka menjadi hal yang sama dari dua sudut pandang yang sedikit berbeda?
S.Lott
1
Tidak yakin saya mengerti dua "sudut pandang yang sedikit berbeda" ini :-(
Combinator Logic
Itulah intinya. Mereka adalah hal yang sama, karenanya kebingungan. Anda hanya memiliki kata-kata yang berbeda tergantung pada sudut pandang Anda: Parsing vs. Code Generation (atau Eksekusi, dalam kasus seorang juru bahasa).
S.Lott
Tidak ada perbedaan. Dengan sedikit imajinasi orang dapat menciptakan representasi sintaksis untuk setiap pohon sintaksis abstrak yang mungkin. Dengan kurangnya imajinasi, ekspresi S Lisp akan menjadi sintaks default yang cocok untuk semuanya.
SK-logic
1
Anda semua harus sudah membaca jawabannya sebelum berkomentar. Ada perbedaan, tetapi memisahkan atau menggabungkannya merupakan masalah implementasi.
Paul

Jawaban:

20

Pohon parse juga dikenal sebagai pohon sintaksis beton.

Pada dasarnya, pohon abstrak memiliki informasi yang lebih sedikit daripada pohon beton. Pohon beton mengandung setiap elemen dalam bahasa, sedangkan pohon abstrak telah membuang potongan-potongan yang tidak menarik.

Misalnya ungkapan: (2 + 5) * 8

Betonnya terlihat seperti ini

  ( 2  + 5 )  * 8
  |  \ | / |  | |
  |   \|/  |  | |
   \___|__/   | |
       \______|/

Sedangkan pohon abstrak memiliki:

2  5 
 \/   
  +  8
   \/
   *

Dalam kasus konkret tanda kurung dan semua bagian bahasa telah dimasukkan ke dalam pohon. Dalam kasus abstrak kurung hilang, karena informasinya telah dimasukkan ke dalam struktur pohon.

Winston Ewert
sumber
Anda lupa menyebutkan di mana kompiler untuk bahasa apa ini diterapkan dengan cara ini. Karena, Anda tahu, Anda tidak harus ... pengurai juga bisa membuang tanda kurung segera.
Ingo
1
@ Ingo, tidak ada dalam jawaban saya yang bisa dikatakan ketika kompiler membuang kurung. Itu menanyakan apa perbedaan antara pohon parse beton dan pohon parse abstrak.
Winston Ewert
Jadi, tentu saja, Anda dapat menyebutkan sumber untuk klaim Anda? Atau ini hanya definisi pribadi Anda?
Ingo
1
@ingo, docs.google.com/document/d/…
Winston Ewert
0

Hal pertama yang perlu Anda pahami adalah bahwa tidak ada yang memaksa Anda untuk menulis parser atau kompiler dengan cara tertentu. Secara khusus, itu tidak selalu berarti bahwa hasil parser harus berupa pohon. Ini bisa berupa struktur data apa saja yang cocok untuk mewakili input.

Misalnya, bahasa berikut:

prog:
      definition 
    | definition ';' prog
    ;

definition: .....

dapat direpresentasikan sebagai daftar definisi. (Nitpickers akan menunjukkan bahwa daftar adalah pohon yang merosot, tetapi bagaimanapun juga.)

Kedua, tidak perlu berpegangan pada pohon parse (atau struktur data apa pun yang dikembalikan parser). Sebaliknya, kompiler biasanya dibangun sebagai urutan lintasan, yang mengubah hasil lintasan sebelumnya. Oleh karena itu tata letak keseluruhan kompiler bisa jadi:

parser :: String             -> Maybe [Definitions]      -- parser
pass1  :: [Definitions]      -> Maybe DesugaredProg      -- desugarer
pass2  :: DesugaredProg      -> Maybe TypedProg          -- type checker
pass3  :: TypedProg          -> Maybe AbstractTargetLang -- code generation
pass4  :: AbstractTargetLang -> Maybe String             -- pretty printer

compiler :: String           -> Maybe String    -- transform source code to target code
compiler source = do
   defs  <- parser source
   desug <- pass1 defs
   typed <- pass2 desug
   targt <- pass3 typed
   pass4 targt

Intinya: Jika Anda mendengar orang berbicara tentang pohon parse , pohon syntac abstrak , pohon sintaks beton dll, selalu mengganti dengan struktur data yang sesuai untuk tujuan tertentu , dan Anda baik-baik saja sedang.

Ingo
sumber
2
Bagaimana ini merupakan jawaban untuk pertanyaan itu?
Winston Ewert
@ WinstonEwert Saya mengklaim bahwa "pohon parse" dan "pohon sintaksis abstrak" adalah abstraksi dan berarti tidak lebih dari "struktur data yang cocok". Jadi, jawabannya adalah bahwa pertanyaan pada umumnya tidak masuk akal, kecuali jika Anda meminta perbedaan antara tipe kembalinya parser dan tipe kembalinya beberapa laluan lain dalam kompiler XY bahasa L.
Ingo