Phunkie: Bangunan Parser Combinators dalam PHP (Bahagian 1)
Tutorial ini, disesuaikan dari blog Inviqa, menunjukkan cara membuat kombinasi parser menggunakan perpustakaan fungsional phunkie untuk PHP. Kami akan memberi tumpuan kepada konsep teras dan membina parser asas, menetapkan peringkat untuk kombinasi yang lebih maju di bahagian berikutnya.
Pengaturcaraan fungsional, dengan penekanannya terhadap fungsi dan komposisi tulen, sangat sesuai untuk membina parser yang mantap dan boleh dikekalkan. Keupayaan untuk menggabungkan fungsi parsing yang lebih kecil dan jelas menjadi lebih besar, yang lebih kompleks adalah kelebihan utama.
Perpustakaan Phunkie menyediakan struktur fungsional yang diperlukan untuk memudahkan proses ini dalam php.
Memahami parsers
Parsing adalah proses mengiktiraf frasa dalam rentetan. Kami akan menggunakan parsing rekursif-descent, teknik yang mudah namun berkuasa.
Combinators: Kuasa Komposisi
Combinator adalah corak yang boleh diguna semula untuk menyusun fungsi. Dalam pengaturcaraan berfungsi, mereka adalah asas untuk membina sistem kompleks dari komponen yang lebih mudah. Kami akan melaksanakan parser sebagai fungsi dan menggunakan gabungan untuk menggabungkannya.
mewakili parser dengan jenis
Parser mengambil rentetan sebagai input dan percubaan untuk memadankan definisi tatabahasa. Hasilnya sama ada perlawanan yang berjaya dengan rentetan yang tinggal atau kegagalan. Kami akan menggunakan jenis Phunkie
untuk mewakili hasil ini: Pasangan yang mengandungi bahagian yang dipadankan dan rentetan yang tinggal. Untuk mengendalikan pelbagai perlawanan yang mungkin, kami akan menggunakan Pair
(senarai tidak berubah). ImmList
dalam php Parser
use Phunkie\Types\Pair; use Phunkie\Types\ImmList; class Parser { private $run; public function __construct(callable $run) { $this->run = $run; } public function run(string $toParse): ImmList { return ($this->run)($toParse); } }
: Sentiasa berjaya, mengembalikan rentetan yang diberikan result(string $a)
dan rentetan input tidak berubah. $a
function result(string $a): Parser { return new Parser(fn(string $s) => ImmList(Pair($a, $s))); }
: Sentiasa gagal, mengembalikan senarai kosong. zero()
function zero(): Parser { return new Parser(fn($s) => Nil()); }
: Menggunakan watak pertama rentetan input. Gagal jika rentetan kosong. item()
function item(): Parser { return new Parser(fn(string $s) => strlen($s) == 0 ? Nil() : ImmList(Pair($s[0], substr($s, 1)))); }
seq
membolehkan penjujukan parser. Ia menggunakan parsers satu demi satu, mengembalikan hasil gabungan. Pelaksanaan naif akan menjadi kompleks dan rawan kesilapan. Sebaliknya, kami memanfaatkan kuasa monad. seq
flatMap
(juga dikenali sebagai flatMap
) adalah komponen utama corak Monad. Ia membolehkan pengiraan pengiraan, mengendalikan hasil satu parser dan lulus mereka ke seterusnya. bind
class Parser { // ... (previous code) ... public function flatMap(callable $f): Parser { return new Parser(function(string $s) use ($f) { return $this->run($s)->flatMap(function(Pair $result) use ($f) { return $f($result->_1)->run($result->_2); }); }); } public function map(callable $f) { return new Parser(function(string $s) use ($f) { return $this->run($s)->map(function(Pair $result) use ($f) { return Pair($f($result->_1), $result->_2); }); }); } }
menggunakan seq
dan flatMap
map
pelaksanaan seq
yang lebih elegan menggunakan flatMap
dan map
:
use Phunkie\Types\Pair; use Phunkie\Types\ImmList; class Parser { private $run; public function __construct(callable $run) { $this->run = $run; } public function run(string $toParse): ImmList { return ($this->run)($toParse); } }
atau, menggunakan Phunkie untuk pemahaman (0.6.0 dan kemudian):
function result(string $a): Parser { return new Parser(fn(string $s) => ImmList(Pair($a, $s))); }
Ini menyimpulkan Bahagian 1. Bahagian 2 akan meneroka lebih banyak kombinasi dan strategi parsing.
Atas ialah kandungan terperinci Pengaturcaraan Fungsian dengan Phunkie: Parser Combinators dalam PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!