Saya ingin memulai dengan ANTLR, tetapi setelah menghabiskan beberapa jam meninjau contoh-contoh di situs antlr.org , saya masih tidak bisa mendapatkan pemahaman yang jelas tentang tata bahasa untuk proses Java.
Apakah ada beberapa contoh sederhana, sesuatu seperti kalkulator empat operasi diimplementasikan dengan ANTLR melalui definisi parser dan semua jalan ke kode sumber Java?
Jawaban:
Catatan : jawaban ini untuk ANTLR3 ! Jika Anda mencari contoh ANTLR4 , maka T&J ini menunjukkan cara membuat pengurai ekspresi sederhana, dan evaluator menggunakan ANTLR4 .
Anda pertama kali membuat tata bahasa. Di bawah ini adalah tata bahasa kecil yang dapat Anda gunakan untuk mengevaluasi ekspresi yang dibangun menggunakan 4 operator matematika dasar: +, -, * dan /. Anda juga dapat mengelompokkan ekspresi menggunakan tanda kurung.
Perhatikan bahwa tata bahasa ini hanya yang sangat mendasar: ia tidak menangani operator yang unary (minus dalam: -1 + 9) atau desimal seperti 0,99 (tanpa nomor utama), untuk menyebutkan hanya dua kekurangan. Ini hanyalah contoh yang bisa Anda kerjakan sendiri.
Berikut isi file tata bahasa Exp.g :
(Aturan Parser mulai dengan huruf kecil, dan aturan lexer dimulai dengan huruf kapital)
Setelah membuat tata bahasa, Anda ingin menghasilkan parser dan lexer darinya. Unduh tabung ANTLR dan simpan di direktori yang sama dengan file tata bahasa Anda.
Jalankan perintah berikut pada shell / command prompt Anda:
Seharusnya tidak menghasilkan pesan kesalahan, dan file ExpLexer.java , ExpParser.java dan Exp.tokens sekarang harus dihasilkan.
Untuk melihat apakah semuanya berfungsi dengan baik, buat kelas tes ini:
dan kompilasi:
dan kemudian jalankan:
Jika semuanya berjalan dengan baik, tidak ada yang dicetak ke konsol. Ini berarti parser tidak menemukan kesalahan. Ketika Anda mengubah
"12*(5-6)"
ke"12*(5-6"
dan kemudian mengkompilasi ulang dan menjalankannya, ada harus dicetak berikut:Oke, sekarang kita ingin menambahkan sedikit kode Java ke tata bahasa sehingga parser benar-benar melakukan sesuatu yang bermanfaat. Menambahkan kode dapat dilakukan dengan menempatkan
{
dan}
di dalam tata bahasa Anda dengan beberapa kode Java sederhana di dalamnya.Tapi pertama-tama: semua aturan parser dalam file tata bahasa harus mengembalikan nilai ganda primitif. Anda dapat melakukannya dengan menambahkan
returns [double value]
setelah setiap aturan:yang perlu sedikit penjelasan: setiap aturan diharapkan menghasilkan nilai ganda. Sekarang untuk "berinteraksi" dengan nilai kembali
double value
(yang TIDAK di dalam blok kode Java biasa{...}
) dari dalam blok kode, Anda harus menambahkan tanda dolar di depanvalue
:Inilah tata bahasa tetapi sekarang dengan kode Java ditambahkan:
dan karena
eval
aturan kami sekarang menghasilkan dua kali lipat, ubah ANTLRDemo.java Anda menjadi ini:Sekali lagi (re) hasilkan lexer dan parser baru dari tata bahasa Anda (1), kompilasi semua kelas (2) dan jalankan ANTLRDemo (3):
dan sekarang Anda akan melihat hasil dari ekspresi yang
12*(5-6)
dicetak ke konsol Anda!Sekali lagi: ini adalah penjelasan yang sangat singkat. Saya mendorong Anda untuk menelusuri wiki ANTLR dan membaca beberapa tutorial dan / atau bermain sedikit dengan apa yang baru saja saya posting.
Semoga berhasil!
EDIT:
Posting ini menunjukkan cara memperluas contoh di atas sehingga
Map<String, Double>
dapat disediakan yang menampung variabel dalam ekspresi yang disediakan.Agar kode ini berfungsi dengan versi Antlr saat ini (Juni 2014), saya perlu melakukan beberapa perubahan.
ANTLRStringStream
diperlukan untuk menjadiANTLRInputStream
, nilai yang dikembalikan perlu diubah dariparser.eval()
keparser.eval().value
, dan saya perlu menghapusWS
klausa di akhir, karena nilai atribut seperti$channel
tidak lagi diizinkan untuk muncul dalam tindakan lexer.sumber
parser.eval()
terjadi? Itu tidak jelas DI SINI atau di Wiki ANTLR3!eval
adalah aturan parser yang mengembalikan adouble
. Jadi adaeval()
metode yang dapat Anda gunakan pada instance dariExpParser
, sama seperti yang saya contohkan diANTLRDemo.main(...)
. Setelah membuat lexer / parser, cukup buka fileExpParser.java
dan Anda akan melihat bahwa adaeval()
metode mengembalikan adouble
.ANTLR mega tutorial oleh Gabriele Tomassetti sangat membantu
Ini memiliki contoh tata bahasa, contoh pengunjung dalam berbagai bahasa (Java, JavaScript, C # dan Python) dan banyak hal lainnya. Sangat dianjurkan.
EDIT: artikel bermanfaat lainnya oleh Gabriele Tomassetti di ANTLR
sumber
Untuk Antlr 4 proses pembuatan kode java di bawah ini: -
Perbarui nama jar Anda di classpath.
sumber
Di https://github.com/BITPlan/com.bitplan.antlr Anda akan menemukan perpustakaan java ANTLR dengan beberapa kelas pembantu yang bermanfaat dan beberapa contoh lengkap. Ini siap digunakan dengan pakar dan jika Anda suka gerhana dan pakar.
https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/main/antlr4/com/bitplan/exp/Exp.g4
adalah bahasa Ekspresi sederhana yang dapat melakukan banyak dan menambah operasi. https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestExpParser.java memiliki unit test yang sesuai untuk itu.
https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/main/antlr4/com/bitplan/iri/IRIParser.g4 adalah parser IRI yang telah dipecah menjadi tiga bagian:
https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestIRIParser.java memiliki unit test untuknya.
Secara pribadi saya menemukan ini bagian yang paling sulit untuk diperbaiki. Lihat http://wiki.bitplan.com/index.php/ANTLR_maven_plugin
https://github.com/BITPlan/com.bitplan.antlr/tree/master/src/main/antlr4/com/bitplan/expr
berisi tiga contoh lagi yang telah dibuat untuk masalah kinerja ANTLR4 di versi sebelumnya. Sementara itu masalah ini telah diperbaiki seperti yang ditampilkan dalam testcase https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestIssue994.java .
sumber
versi 4.7.1 sedikit berbeda: untuk impor:
untuk segmen utama - perhatikan CharStreams:
sumber