Pegjs: Bagaimana cara mempertahankan pemisah spasi putih?

Dibuat pada 3 Okt 2019  ·  6Komentar  ·  Sumber: pegjs/pegjs

Jenis masalah

  • Laporan Bug: _no_
  • Permintaan Fitur: _no_
  • Pertanyaan: _ya_
  • Bukan masalah: _no_

Prasyarat

  • Bisakah Anda mereproduksi masalah?: _yes_
  • Apakah Anda mencari masalah repositori?: _yes_
  • Apakah Anda memeriksa forum?: _yes_
  • Apakah Anda melakukan pencarian web (google, yahoo, dll)?: _yes_

Saya berjuang untuk membuat parser PEG.js mempertahankan spasi putih asli dari persamaan.

Perilaku saat ini: 2 * 5 + SUM(1, 2, 3)

[
   "2",
   "*",
   "5",
   "+",
   "SUM",
   "(",
   [
      "1",
      ",",
      "2",
      ",",
      "3"
   ],
   ")"
]

Perilaku yang diinginkan : 2 * 5 + SUM(1, 2, 3)

[
   "2",
   " ",
   "*",
   " ",
   "5",
   " ",
   "+",
   " ",
   "SUM",
   "(",
   [
      "1",
      ",",
      " ",
      "2",
      ",",
      " ",
      "3"
   ],
   ")"
]

Tata bahasa untuk disalin: https://Pastebin.com/zpwqT6Uw
Taman bermain PEG.js https://pegjs.org/online

Apa yang saya lewatkan?

Komentar yang paling membantu

@marek-baranowski Ping lembut lainnya :smiley_cat:

Juga, saya menulis plugin PEG.js pegjs-syntactic-actions untuk memfasilitasi debugging tata bahasa, dan secara khusus melihat karakter apa yang ditangkap oleh aturan apa yang terlepas dari tindakan, yang mungkin menjadi masalah Anda di sini seperti yang dijelaskan oleh @StoneCypher.

Alasan plugin ini adalah: Saya merasa sering/kadang sulit untuk memahami hasil global ketika itu tidak seperti yang kita harapkan, karena hasil dari kombinasi banyak tindakan kecil, dan menemukan tindakan yang berperilaku buruk/aneh bisa jadi membuang-buang waktu. Dengan plugin ini, kita melihat aturan apa yang menangkap karakter apa, dan itu memberi nama tindakan untuk ditindaklanjuti.

Semua 6 komentar

@futagoza sangat menyesal mengganggu Anda tetapi ini adalah pertama kalinya saya berurusan dengan PEG.js dan masalah ini sangat penting bagi saya. Bolehkah saya meminta sedikit petunjuk?

Salam Hormat,
Marek

Saya mencoba melihat-lihat tata bahasa Anda (kemarin dan barusan) tetapi karena sangat sulit untuk memahaminya (mengesampingkan konvensi penamaan, formatnya, sejujurnya, ada di mana-mana), saya butuh beberapa saat untuk melacak solusi:

  1. Aturan yang menghabiskan ruang & data mengembalikannya (misalnya const mengembalikan [left_space, cnst, right_space] )
  2. Aturan/tindakan apa pun yang mengambil hasil harus melakukan sesuatu seperti ini: [].concat.apply([], con)

Meski begitu, jujur ​​​​dengan Anda ini terasa seperti solusi hacky bagi saya. Apakah Anda punya link ke spec atau sesuatu? Akan membantu untuk mengetahui aturan apa yang dapat dan tidak dapat saya ubah untuk mendapatkan hasil yang diinginkan tanpa solusi peretasan di atas.

Jika tidak, selama Anda bersedia meluangkan waktu dan merapikan tata bahasa dan mengganti nama beberapa aturan (sehingga lebih mudah untuk mengetahui apa yang Anda inginkan), maka saya akan dengan senang hati mencoba untuk mencoba lagi

@marek-baranowski - Maaf saya tidak melihat ini sampai sekarang. Semoga ini masih berguna untuk Anda

Jika Anda ingin mempertahankan spasi, perlakukan saja seperti konten yang cocok.

Tidak terlalu jelas apa yang Anda inginkan untuk dua spasi. Anda bisa memiliki string dua spasi, atau array dua string satu spasi. Biasanya saya mengharapkan yang pertama, tapi ... semua yang Anda miliki adalah per karakter

Juga ... mengapa Anda menginginkan karakter liar seperti itu, kecuali untuk panggilan fungsi? Pengurai harus merangkumnya untuk Anda.

Bagaimanapun

Inilah yang Anda minta:

Document = Expression*

Whitespace
  = tx:[ \r\n]+ { return tx.join(''); }

Number
  = str:[0-9]+ { return str.join(''); }

Oper
  = '+'
  / '-'
  / '/'
  / '*'
  / ','

Label
  = l:[a-zA-Z]+ { return l.join(''); }

Parens 
  = '(' Whitespace? ex:Expression* Whitespace? ')' { return ex; }

Expression 
  = Number 
  / Oper
  / Whitespace
  / Label
  / Parens
  / [^()]+

image

Masalahnya, saya tidak terlalu yakin bahwa itu sebenarnya yang Anda inginkan. Sebagai gantinya, Anda dapat mengurai angka dan operator, dan mengembalikan bentuk simpul standar untuk masing-masing operator:

Document = Expression*

Whitespace
  = tx:[ \r\n]+ { return { 
    ast: 'whitespace', value: tx.join('') 
  }; }

Number
  = str:[0-9]+ { return {
    ast: 'number', value: parseInt(str,10)
  }; }

Oper
  = '+' { return { ast: 'oper', value: 'add' }}
  / '-' { return { ast: 'oper', value: 'subtract' }}
  / '/' { return { ast: 'oper', value: 'divide' }}
  / '*' { return { ast: 'oper', value: 'multiply' }}
  / ',' { return { ast: 'oper', value: 'sequence' }}

Label
  = l:[a-zA-Z]+ { return { 
    ast: 'label', value: l.join('') 
  }; }

Parens 
  = '(' Whitespace? ex:Expression* Whitespace? ')' { 
    return { ast: 'parens', value: ex 
  }; }

Expression 
  = Number 
  / Oper
  / Whitespace
  / Label
  / Parens
  / [^()]+

Sekarang Anda masih memiliki spasi, tetapi Anda juga memiliki pohon parsing yang tepat, dan tidak perlu menulis parser untuk mengurai output parser Anda, dan sekarang juga sangat mudah untuk mulai menambahkan fitur reguler seperti nomor baris dan sebagainya

image

@marek-baranowski - Saya ingin mengurangi ukuran pelacak masalah ini

Jika di atas adalah apa yang Anda butuhkan, tolong pertimbangkan untuk menutup masalah ini? Terima kasih

Jika tidak, beri tahu saya alasannya, dan saya akan mencoba lagi

@marek-baranowski Ping lembut lainnya :smiley_cat:

Juga, saya menulis plugin PEG.js pegjs-syntactic-actions untuk memfasilitasi debugging tata bahasa, dan secara khusus melihat karakter apa yang ditangkap oleh aturan apa yang terlepas dari tindakan, yang mungkin menjadi masalah Anda di sini seperti yang dijelaskan oleh @StoneCypher.

Alasan plugin ini adalah: Saya merasa sering/kadang sulit untuk memahami hasil global ketika itu tidak seperti yang kita harapkan, karena hasil dari kombinasi banyak tindakan kecil, dan menemukan tindakan yang berperilaku buruk/aneh bisa jadi membuang-buang waktu. Dengan plugin ini, kita melihat aturan apa yang menangkap karakter apa, dan itu memberi nama tindakan untuk ditindaklanjuti.

oh wow ini benar-benar rapi sebenarnya

Apakah halaman ini membantu?
0 / 5 - 0 peringkat