Pegjs: Forum atau obrolan? Melewati nilai ke bawah / memunculkan nilai ke atas?

Dibuat pada 23 Mar 2017  ·  7Komentar  ·  Sumber: pegjs/pegjs

pegjs sederhana dan kuat. Aku menyukainya! Saya memiliki beberapa pertanyaan yang tidak tercakup dalam dokumen:

Saya menguraikan ini, yang berfungsi, tetapi aturannya tampak canggung:

f = x => x * x

Jika saya mendelegasikannya untuk mengatakan Operator, tidak ada cara untuk menurunkan nilai. Jika saya membuat ValuesOperators dan atau = dan =>, ini sedikit lebih bersih, tetapi di tingkat atas saya masih perlu memeriksa yang mana. Dalam contoh JavaScript, saya melihat penggunaan { type: "Literal", value: ... }. Apakah itu cara terbaik untuk meneruskan informasi kembali?

  = values:Values body:(_ "=>" _ Expression)? assign:(_ "=" _ Expression)? {
      if (body && body.length > 0) {
        return new Function(values, body[3]);
      } else if (assign) {
        return new Assignment(values, assign[3]);
      } else {
        return values;
      }
    }

Terima kasih!
mike

Komentar yang paling membantu

Saya berasumsi bahwa tidak mundur dan serakah berarti Anda harus bekerja dengan "di mana pun Anda berada", tetapi bukan itu masalahnya. Ya!

Serakah hanya berarti jika menemukan kecocokan, ia akan mengambilnya, benar? Tetapi jika seluruh aturan tidak cocok, itu akan dimulai lagi dari awal di pertandingan berikutnya. Ini membuatnya jauh lebih mudah daripada bagaimana saya pertama kali mencoba melakukannya.

x, y = 2 + 3.foo + "foo", 5 * 2

Ini cukup mudah ketika tugas dapat dicocokkan secara terpisah dari ekspresi reguler, dll.

  = Assignment
  / Expression

Assignment
  = vars:Variables _ "=" _ expr:Expression

Variables
  = head:Identifier tail:(_ "," _ Identifier)*

...

Semua 7 komentar

Dalam tata bahasa, penting untuk memahami aturan. Dan Anda hanya menyediakan sub .. ini tidak jelas bagi saya, bagaimana bisa jelas untuk mesin?
Tata bahasa LALR sangat sulit untuk ditulis tetapi lebih mudah daripada LR dan lebih mudah dari LL..
Tata bahasa PEG mudah ditulis bud paling sulit untuk menulis secara efisien.
Apakah Anda yakin Anda menggunakan mainan yang tepat? Jika Anda memiliki tata bahasa PEG yang bagus, Anda harus dapat membuat transpiler atau menafsirkan semudah menafsirkan aturan Anda.

Apakah Anda tahu tinju/unboxing di mesin virtual?

Bagaimana Anda dapat memiliki values di sisi kiri tugas? karena Anda memiliki ini: body:(_ "=>" _ Expression)? diakhiri dengan ?

apa arti values dalam tata bahasa Anda? Apakah Anda tahu apa itu nilai-L ?

Anda harus menjaga agar tata bahasa Anda tetap dekat secara semantik. Sulit dengan PEG dalam beberapa kasus.. { type: "Literal", value: ... } adalah persis apa yang Anda butuhkan di AST. Lihat http://astexplorer.net/ seperti apa bentuknya

Saya baru saja mulai menggunakannya untuk bereksperimen, jadi ya, beberapa penamaannya salah :) Saya telah menulis beberapa parser LL(1) sederhana, tetapi sudah lama. Saya hanya ingin tahu apa cara terbaik untuk menangani keputusan. Saya akan menyederhanakan untuk sintaks ini:

a = b
atau
x => x * x

Apakah lebih tepat untuk melakukan sesuatu seperti ini?

TugasAtauFungsi
= ident: Operator pengidentifikasi:IdentOperator {
if (operator.type === "Fungsi") {
...
}

IdentOperator
= "=" !">" { return { ketik: "Tugas"; } }
/ "=>" { ... }

FYI, "nilai" adalah istilah yang saya maksudkan dengan daftar item - mereka akan menjadi nilai jika digunakan sebagai Tuple, tetapi variabel jika digunakan untuk mendefinisikan argumen fungsi. Misalnya (2 + 3).

Terima kasih atas waktunya!

@mikeaustin Ada di tangan Anda :-)

Menulis tata bahasa adalah tentang pengurangan . Paling atas adalah pernyataan . Ini seperti kalimat, Anda tahu, Anda memiliki tata bahasa LL :-)

Adalah tanggung jawab Anda untuk mendefinisikan tata bahasa dalam arti (maaf saya memiliki masalah dengan bahasa Inggris :-D kadang-kadang)

Bagaimana Anda ingin memproses AssignmentOrFunction? Ini pada dasarnya sama dengan pernyataan dalam banyak bahasa, tetapi juga dapat menjadi nilai-R .
Di sisi lain

    = "=" !">" { return { type: "Assignment"; } }
    / "=>" { ... }

dapat lebih baik ditulis sebagai

    = "=>" { ... }
    / "=" { return { type: "Assignment"; } }

Mungkin saya salah.. tapi ini sepertinya Anda memecah kalimat Anda menjadi bagian yang tidak begitu penting. Tanpa konteks, tidak terlalu penting apa yang Anda evaluasi ini..

PEG sangat sulit untuk ditulis karena Anda dapat dengan mudah menulis aturan yang tidak dapat dijangkau atau Anda dapat menulis aturan yang akan mencuri kalimat Anda dan mengevaluasinya secara salah, jadi jika Anda pemula, Anda harus memiliki kalimat di kiri dan AST yang diperlukan di kanan sepanjang waktu, sepuluh kali lebih banyak tes otomatis daripada aturan tata bahasa. Percayalah, Anda mengubah satu aturan dan seluruh parser Anda akan rusak..

Dan tentu saja Anda harus bermain dengan, menulis sesuatu, lagi dan lagi.. Tidak sepele untuk menulis kalkulator ekspresi efektif dengan PEG, perhatikan beberapa tingkat prioritas.. PEG lebih baik untuk parsing umum.

Anda tidak memberi saya lebih banyak konteks dalam pertanyaan Anda sehingga sangat sulit untuk menebak apa yang sebenarnya ingin Anda buat, tetapi saya dapat menebak Anda harus lebih banyak bermain dengan tata bahasa, ada AntLR , alat yang hebat untuk belajar, GoldParser (LALR) (saya mainan pertama :-) ), beberapa parser sekolah lama yang diuji dengan baik, paling efisien tetapi dipecah menjadi tokenizer/parser (lex dan yacc yang lebih lama, flex dan bison yang lebih baru), banyak port di antaranya..

PEG terlihat seperti yang paling sederhana. Ini benar-benar. Tapi itu akan selalu menjadi yang paling berbahaya...

Terima kasih banyak! Oh, saya memang menemukan grup Google untuk pegjs, tetapi tidak menyadarinya karena berada di bagian pengembangan. Jika saya memiliki pertanyaan lain, saya pasti akan pergi ke sana.

Ya, tugas "x = y" adalah _pernyataan_, tetapi "x => x * x" dapat menjadi bagian dari _ekspresi_, serta "x == y", dll. "=" adalah kasus khusus, dan seterusnya adalah "=>" dalam arti bahwa mereka bukan operator biasa. Saya akan berlatih lebih banyak, dan melihat lebih dekat pada contoh-contohnya. Saya berharap ada contoh yang lebih besar dari kalkulator, tetapi lebih kecil dari contoh lainnya. Mungkin jika saya membuat kemajuan itu bisa menjadi contoh :)

Untuk proyek saya, saya ingin menulis bahasa sederhana untuk transpile ke JS. Dasar-dasarnya adalah eksternal, metode cakupan leksikal (tidak ada patch monyet, seperti Dylan atau CLOS tetapi tanpa multimetode), argumen kata kunci, ADT, bahkan mungkin pengetikan statis opsional. "Sederhana" berarti semuanya bekerja sama, dan hanya ada satu cara untuk melakukan sesuatu. Membuat sesuatu yang sederhana bisa menjadi _hard_.

Juga, ada perpustakaan seperti adt dan multimethods yang dapat mengambil manfaat dari sintaks asli. Itu sebenarnya bisa dicapai dengan sweet , tapi sweet hanya bisa memperpanjang JS, bukan membuatnya lebih sederhana. TypeScript memiliki opsi seperti "--strictNullChecks" dan mendukung jenis serikat sebaris, tetapi sekali lagi, ia memperluas JS sehingga meninggalkan semua hal buruk masih ada (pemaksaan implisit, "+" untuk penggabungan string, pengangkatan ruang lingkup, dll.).

Sekali lagi, terima kasih atas semua bantuannya!
mike

Saya berasumsi bahwa tidak mundur dan serakah berarti Anda harus bekerja dengan "di mana pun Anda berada", tetapi bukan itu masalahnya. Ya!

Serakah hanya berarti jika menemukan kecocokan, ia akan mengambilnya, benar? Tetapi jika seluruh aturan tidak cocok, itu akan dimulai lagi dari awal di pertandingan berikutnya. Ini membuatnya jauh lebih mudah daripada bagaimana saya pertama kali mencoba melakukannya.

x, y = 2 + 3.foo + "foo", 5 * 2

Ini cukup mudah ketika tugas dapat dicocokkan secara terpisah dari ekspresi reguler, dll.

  = Assignment
  / Expression

Assignment
  = vars:Variables _ "=" _ expr:Expression

Variables
  = head:Identifier tail:(_ "," _ Identifier)*

...

@mikeaustin PEG telah memesan pilihan yang berarti bahwa pola pertama yang cocok dalam ekspresi akan secara otomatis cocok. Contoh @langpavel adalah cara yang baik untuk mengekspresikan preferensi untuk => lebih dari = . Anda mungkin ingin lebih memikirkan apa ekspresi dalam istilah "salah satu dari hal-hal ini" daripada "ambil semua teks ini yang bisa menjadi ekspresi dan cari tahu nanti"

  = FunctionExpression
  / Assignment
  / Value

Untuk mendemonstrasikannya, saya membuat tata bahasa uji yang dapat Anda mainkan. Agak bising tapi saya sudah mencoba membuatnya cukup sederhana, mengabaikan beberapa hal seperti mengizinkan spasi ekstra dan operator. Perhatikan blok Expression tempat keajaiban terjadi. Juga, saya telah menggunakan hal-hal seperti SubExpression dan ExpressionList sebagai cara untuk menangani situasi "banyak dari ini"; pola itu berfungsi dengan baik untuk saya menjaga pemisah daftar dan item terpisah.

Dalam setiap kasus, saya mencoba menjaga tata bahasa tetap sederhana dengan memiliki satu item untuk setiap jenis kecocokan. Ada beberapa redundansi yang terlibat karena saya bisa menulis ulang sehingga kita memiliki satu urutan kecocokan besar dengan semua kemungkinan kombinasi tapi itu sulit untuk diikuti dan alasan dan meninggalkan ambiguitas terbuka yang PEG dapat menghilangkan dengan pilihan yang dipesan. Semoga membantu.

Saya akan melihat tata bahasa tes, terima kasih! Ini membantu untuk melihat subset minimal bahasa karena tata bahasa JavaScript cukup besar.

@dmsnell Saya belajar banyak akhir-akhir ini dengan menghapus aturan dan menambahkan beberapa aturan baru ke tata bahasa JavaScript, Anda dapat melihat yang terbaru di sini: impuls.pegjs . Saya telah menghapus sintaks elision [,,], beberapa operator, ekspresi urutan, dll. dan menambahkan sintaks Tuple (1, 2) dan sintaks rentang 1.5. Angka floating point memerlukan desimal di kedua sisi untuk membuat rentang literal lebih mudah diuraikan.

Saya telah mengerjakan banyak runtime akhir-akhir ini, tetapi ingin kembali ke parser untuk benar-benar memancarkan JavaScript. Saya di antara pekerjaan jadi saya punya sedikit waktu di tangan saya :) Beberapa ide untuk dialek JavaScript yang dibersihkan dengan metode ekstensi, parameter bernama, sifat dan mixin, kelebihan operator dan tupel literal dan sintaks jangkauan.

Terima kasih lagi!
mike

Apakah halaman ini membantu?
0 / 5 - 0 peringkat