Saya sedang menulis pengurai kalkulator membosankan lainnya dengan Spirit X3 dan saya menghadapi masalah: Saya telah mendefinisikan 2 literal, "cos" dan "cosh", yang masing-masing berharap diikuti oleh angka. Aturan yang saya tulis adalah:

const std::string COS_TAG = "cos";
const std::string COSH_TAG = "cosh";
const auto cos = (COS_TAG > value)[math::cos_solver{}];
const auto cosh = (COSH_TAG > value)[math::cosh_solver{}];

(Saya tahu tindakan semantik bukan cara yang disukai, tapi saya malas). Sekarang, masalah saat mem-parsing "cosh 3.5" adalah:

expectation failure: expecting value here "cosh 3.5"
----------------------------------------------^-----

Sepertinya parser bersemangat dan menggunakan tag pertama tanpa memeriksa yang lain. Saya telah membuatnya bekerja dengan menggunakan operator perbedaan seperti ini:

const std::string COS_TAG = "cos";
const std::string COSH_TAG = "cosh";
const auto cos = ((x3::lit(COS_TAG) - COSH_TAG) > value)[math::cos_solver{}];
const auto cosh = (COSH_TAG > value)[math::cosh_solver{}];

Apakah ada pendekatan yang lebih baik?

1
Etchelon 9 Agustus 2019, 10:49

1 menjawab

Jawaban Terbaik

Jadi, bukan string yang dibatasi, lebih baik periksa batas token.

Repositori Qi memiliki distinct untuk ini dan saya pikir saya mungkin pernah melihatnya di basis kode X3 sekali. Akan mencarinya.

Terlepas dari itu, untuk saat ini/versi lama/pemahaman Anda, berikut adalah beberapa cara untuk mencapainya:

  • pesan ulang cabang, jika Anda mencocokkan cosh sebelum cos Anda mendapatkan perilaku yang Anda inginkan karena keserakahan

  • buat pernyataan yang lebih umum tentang pengenal Anda:

    auto kw = [](auto p) {
         return x3::lexeme [ x3::as_parser(p) >> !x3::char_("a-zA-Z0-9_") ];
    };
    

    Sekarang alih-alih lit(COSH) Anda dapat menggunakan kw(COSH) dan pastikan itu tidak cocok dengan coshida.

2
sehe 9 Agustus 2019, 14:57