Bagi mereka yang tidak mengikuti POJ (Pascal pada JVM) ia adalah pengkompil yang mengubah subset daripada Pascal kepada JASM ( Java Assembly) supaya kita boleh menggunakan JVM sebagai persekitaran pelaksanaan.
Dalam siaran lepas, kami telah menyelesaikan beberapa pepijat penting, terutamanya dalam penjanaan pemasangan. Dalam siaran ini kita akan bercakap tentang cara menjana himpunan dengan betul untuk ayat bersarang.
Ketika kami sedang menyusun untuk JVM, adalah perlu untuk memperincikan fungsi pelbagai titik mesin maya yang luar biasa ini. Oleh itu, pada pelbagai masa saya memperincikan fungsi dalaman JVM serta beberapa arahannya (opcodes).
Salah satu ciri yang diperlukan untuk menangani ayat bersarang dengan betul ialah kemungkinan mempunyai berbilang konteks dalam penghurai. Ini kerana jika penghurai menganggap satu konteks sahaja, ayat kawalan bersarang yang menjana label dan melompat (seperti jika, untuk, semasa dan ulang) akan menjana pengalamatan lompat dengan salah.
Terdapat dua cara untuk menangani konteks, iaitu:
Biasanya saya akan menggunakan pendekatan parser rekursif. Walau bagaimanapun, untuk melaksanakan penghurai rekursif dengan ANTLR, disebabkan oleh cara tatabahasa distrukturkan dalam POJ, adalah perlu untuk menyuntik kod terus ke dalam tatabahasa, pendekatan yang tidak disyorkan. Akibatnya, kami memilih pendekatan menyusun konteks.
Memandangkan sudah ada pelaksanaan tindanan yang memantau jenis yang penghuraikan disusun/dinyahtindan dalam JVM, untuk tidak perlu mencipta tindanan lain untuk jenis tertentu, kami memutuskan untuk mencipta satu tindan generik dalam PR ini. Selain dapat memanfaatkan pelaksanaan ini kemudian, saya masih boleh memfaktorkan semula kod lama dan mengalih keluar tindanan khusus sedia ada.
Dalam komit ini penghuraikan telah ditukar kepada tindanan/nyahtindan konteks fungsi dengan betul. Pada asasnya pada permulaan penghuraikan fungsi konteks disusun dan pada penghujungnya konteks dinyahtindan.
Kawal ayat seperti jika, untuk, semasa dan ulang berfungsi dengan betul. Walau bagaimanapun, jika terdapat ayat bersarang, POJ tidak menyimpan konteks dan akhirnya tersilap menjana label dan melompat. Di sini dan di sini dibincangkan cara penjanaan himpunan berfungsi untuk ayat kawalan ini.
Untuk contoh di bawah, yang mengandungi jika bersarang di dalam yang lain, POJ tersilap menjana label dan lompatan yang diperlukan:
program NestedIfs; begin if (1 > 2) then if (2 > 3 ) then writeln('1 > 2 and 2 > 3') else writeln('1 > 2 and 2 <= 3') else writeln('1 <= 2'); end.
Pepijat ini diketahui dan saya memilih untuk menyelesaikannya apabila penghurai menyokong konteks.
Dalam komit ini, struktur LabelsContext telah dibuat mengandungi label berikut:
Untuk mengesahkan penjanaan yang betul pemasangan, ujian telah dibuat untuk mengesahkan jika bersarang, bersarang ulang, bersarang sementara serta untuk's bersarang. Ujian dibuat di sini untuk mengesahkan penjanaan pemasangan dalam kes fungsi rekursif. Tambahan pula, adalah perlu untuk mengemas kini pemasangan yang dijangkakan bagi semua ujian sedia ada. Akhirnya, dalam PR ini parser telah dikemas kini untuk menggunakan struktur konteks baharu.
Berikut ialah PR lengkap perubahan ini. Di sini kita mempunyai komit yang mengandungi perubahan untuk fungsi yang betul bagi ayat jika, di sini komit merujuk kepada ulang, di sini komit merujuk kepada semasa dan di sini komit merujuk kepada untuk.
Dalam post seterusnya kita akan bercakap tentang kemasukan data. Kini tidak lama lagi kami menyelesaikan salah satu objektif projek ini: membaca nombor daripada input standard dan mengira pemfaktorannya.
Repositori dengan kod dan dokumentasi lengkap projek ada di sini.
Atas ialah kandungan terperinci Ayat bersarang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!